diff --git a/Android.bp b/Android.bp index 4f5e3c4..0969ce6 100644 --- a/Android.bp +++ b/Android.bp @@ -353,15 +353,44 @@ cc_library_static { export_include_dirs: [ "common", "encoder", + "encoder/drc_src", ], srcs: [ "common/ixheaac_esbr_fft.c", "common/ixheaac_esbr_rom.c", "common/ixheaac_fft_ifft_32x32_rom.c", + "encoder/iusace_acelp_enc.c", + "encoder/iusace_acelp_rom.c", + "encoder/iusace_acelp_tools.c", + "encoder/iusace_arith_enc.c", + "encoder/iusace_avq_enc.c", + "encoder/iusace_avq_rom.c", + "encoder/iusace_block_switch.c", "encoder/iusace_bitbuffer.c", + "encoder/iusace_enc_fac.c", + "encoder/iusace_enc_main.c", + "encoder/iusace_esbr_inter_tes.c", + "encoder/iusace_esbr_pvc.c", + "encoder/iusace_esbr_pvc_rom.c", + "encoder/iusace_esbr_rom.c", + "encoder/iusace_fd_fac.c", "encoder/iusace_fft.c", + "encoder/iusace_lpc.c", + "encoder/iusace_lpc_avq.c", + "encoder/iusace_lpd_enc.c", + "encoder/iusace_lpd_rom.c", + "encoder/iusace_lpd_utils.c", + "encoder/iusace_ms.c", + "encoder/iusace_psy_rom.c", + "encoder/iusace_psy_mod.c", + "encoder/iusace_psy_utils.c", "encoder/iusace_rom.c", + "encoder/iusace_tcx_enc.c", + "encoder/iusace_tcx_mdct.c", + "encoder/iusace_tns_usac.c", + "encoder/iusace_windowing.c", + "encoder/iusace_write_bitstream.c", "encoder/ixheaace_adjust_threshold.c", "encoder/ixheaace_api.c", "encoder/ixheaace_asc_write.c", @@ -373,9 +402,15 @@ cc_library_static { "encoder/ixheaace_calc_ms_band_energy.c", "encoder/ixheaace_channel_map.c", "encoder/ixheaace_common_rom.c", + "encoder/ixheaace_cplx_pred.c", "encoder/ixheaace_dynamic_bits.c", "encoder/ixheaace_enc_init.c", "encoder/ixheaace_enc_main.c", + "encoder/ixheaace_fd_enc.c", + "encoder/ixheaace_fd_mdct.c", + "encoder/ixheaace_fd_qc_adjthr.c", + "encoder/ixheaace_fd_qc_util.c", + "encoder/ixheaace_fd_quant.c", "encoder/ixheaace_fft.c", "encoder/ixheaace_group_data.c", "encoder/ixheaace_huffman_rom.c", @@ -403,6 +438,7 @@ cc_library_static { "encoder/ixheaace_mps_tree.c", "encoder/ixheaace_mps_vector_functions.c", "encoder/ixheaace_ms_stereo.c", + "encoder/ixheaace_nf.c", "encoder/ixheaace_ps_bitenc.c", "encoder/ixheaace_ps_enc.c", "encoder/ixheaace_ps_enc_init.c", @@ -425,6 +461,8 @@ cc_library_static { "encoder/ixheaace_sbr_frame_info_gen.c", "encoder/ixheaace_sbr_freq_scaling.c", "encoder/ixheaace_sbr_hbe_dft_trans.c", + "encoder/ixheaace_sbr_hbe_fft_ifft_32x32.c", + "encoder/ixheaace_sbr_hbe_polyphase.c", "encoder/ixheaace_sbr_hbe_trans.c", "encoder/ixheaace_sbr_inv_filtering_estimation.c", "encoder/ixheaace_sbr_main.c", @@ -440,6 +478,8 @@ cc_library_static { "encoder/ixheaace_sbr_tran_det_hp.c", "encoder/ixheaace_sbr_write_bitstream.c", "encoder/ixheaace_sf_estimation.c", + "encoder/ixheaace_signal_classifier.c", + "encoder/ixheaace_signal_classifier_rom.c", "encoder/ixheaace_static_bits.c", "encoder/ixheaace_stereo_preproc.c", "encoder/ixheaace_tns.c", @@ -448,6 +488,14 @@ cc_library_static { "encoder/ixheaace_tns_params.c", "encoder/ixheaace_write_adts_adif.c", "encoder/ixheaace_write_bitstream.c", + "encoder/drc_src/impd_drc_api.c", + "encoder/drc_src/impd_drc_enc.c", + "encoder/drc_src/impd_drc_gain_calculator.c", + "encoder/drc_src/impd_drc_gain_enc.c", + "encoder/drc_src/impd_drc_mux.c", + "encoder/drc_src/impd_drc_tables.c", + "encoder/drc_src/impd_drc_uni_drc_eq.c", + "encoder/drc_src/impd_drc_uni_drc_filter_bank.c", ], sanitize: { diff --git a/CMakeLists.txt b/CMakeLists.txt index 9762750..82539b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,3 +26,4 @@ include("${XAAC_ROOT}/fuzzer/xaac_dec_fuzzer.cmake") include("${XAAC_ROOT}/encoder/libxaacenc.cmake") include("${XAAC_ROOT}/test/encoder/xaacenc.cmake") include("${XAAC_ROOT}/fuzzer/xaac_enc_fuzzer.cmake") + diff --git a/README.md b/README.md index cac8759..d1224b7 100644 --- a/README.md +++ b/README.md @@ -8,13 +8,14 @@ As the Extended High Efficiency AAC Profile is a logical evolution of the MPEG A One of the key features of libxaac (refer to above image) is that it has support for AAC-LD (Low Delay), AAC-ELD (Enhanced Low Delay), and AAC-ELDv2 (Enhanced Low Delay version 2) modes. AAC-LD mode provides low latency encoding, making it suitable for applications such as interactive communication and live audio streaming. It helps to reduce the delay in the encoding process to improve the real-time performance of the system. AAC-ELD mode improves the low-delay performance of HE-AAC by reducing the coding delay while maintaining high audio quality. It was observed that minimum delay it can achieve is 15ms. In order to achieve low delay coding scheme and low bitrate, it uses the Low Delay SBR tool. AAC-ELDv2 is the most advanced version of AAC-based low delay coding. It provides an enhanced version of AAC-ELD, which provides even lower coding delay and higher audio quality. +MPEG-D USAC, also known as Unified Speech and Audio Coding, is designed to provide high-quality audio coding at low bit rates. MPEG-D USAC combines advanced audio coding techniques with state-of-the-art speech coding algorithms to achieve significant compression gains while maintaining perceptual audio quality. The standard supports a wide range of audio content, including music, speech, and mixed audio, making it versatile for different use cases. With its ability to deliver high-fidelity audio at reduced bit rates, MPEG-D USAC plays a crucial role in optimizing bandwidth usage and enhancing the user experience in the digital audio domain. + Overall, libxaac, with support for AAC-LD, AAC-ELD, and AAC-ELDv2 modes, is a versatile audio coding technology that can be used for a wide range of applications, such as broadcasting, streaming, and teleconferencing which requires high-quality audio compression with minimal delay. -Also, the libxaac decoder supports MPEG-D DRC (Dynamic Range Control) for the Extended HE-AAC profile. MPEG-D DRC offers a bitrate efficient representation of dynamically compressed versions of an audio signal. This is achieved by adding a low-bitrate DRC metadata stream to the audio signal. DRC includes dedicated sections for metadata-based loudness leveling, clipping prevention, ducking, and for generating a fade-in and fade-out to supplement the main dynamic range compression functionality. The DRC effects available at the DRC decoder are generated at the DRC encoder side. At the DRC decoder side, the audio signal may be played back without applying DRC, or an appropriate DRC effect is selected and applied based on the given playback scenario. It offers flexible solutions to efficiently support the widespread demand for technologies such as loudness normalization and dynamic range compression for various playback scenarios. - +Also, the libxaac supports MPEG-D DRC (Dynamic Range Control) for the Extended HE-AAC profile in both encoder and decoder. MPEG-D DRC offers a bitrate efficient representation of dynamically compressed versions of an audio signal. This is achieved by adding a low-bitrate DRC metadata stream to the audio signal. DRC includes dedicated sections for metadata-based loudness leveling, clipping prevention, ducking, and for generating a fade-in and fade-out to supplement the main dynamic range compression functionality. The DRC effects available at the DRC decoder are generated at the DRC encoder side. At the DRC decoder side, the audio signal may be played back without applying DRC, or an appropriate DRC effect is selected and applied based on the given playback scenario. It offers flexible solutions to efficiently support the widespread demand for technologies such as loudness normalization and dynamic range compression for various playback scenarios. #### Note -* MPEG-D USAC (along with MPEG-D DRC) support for libxaac encoder will be coming soon, which will help in improved audio quality at reduced bitrates. USAC technology will provide efficient and high quality compression of speech and audio signals, making it a valuable addition to our libxaac capabilities and features. +* The operating points for MPEG-D USAC (along with MPEG-D DRC) in libxaac encoder is currently restricted to 64 kbps and 96 kbps. It is recommended to use the encoder at these operating points only. The support shall be extended to other operating points soon. * Further Quality enhancements for AAC-ELD and AAC-ELDv2 modes may be pushed as quality assessment is in progress. # Building the libxaac decoder and encoder diff --git a/README_enc.md b/README_enc.md index ed0f5c9..8f0d152 100644 --- a/README_enc.md +++ b/README_enc.md @@ -20,29 +20,38 @@ |23|AAC-LD| |29|HE-AACv2| |39|AAC-ELD| -|42|USAC (support will be added soon)| +|42|USAC| # Running the libxaac encoder The libxaac encoder can be run by providing command-line parameters(CLI options) directly or by providing a parameter file as a command line argument. The reference paramfile is placed in `encoder\test` directory(paramfilesimple.txt) +The configuration file for DRC is placed in `encoder\test` directory(impd_drc_config_params.txt). Please make sure this file is placed in the same directory as the executable. # Command line usage : ``` -ifile: -ofile: [options] (or) -paramfile: - [options] can be, [-br:] [-mps:] [-adts:] [-tns:] +[-nf:] +[-cmpx_pred:] [-framesize:] [-aot:] [-esbr:] -[-full_bandwidth:] +[-full_bandwidth:] [-max_out_buffer_per_ch:] [-tree_cfg:] +[-usac:] +[-ccfl_idx:] +[-pvc_enc:] +[-harmonic_sbr:] +[-esbr_hq:] +[-drc:] +[-inter_tes_enc:] where, is the parameter file with multiple commands @@ -52,26 +61,46 @@ where, Valid values are 0 (disable MPS) and 1 (enable MPS). Default is 0. Valid values are 0 ( No ADTS header) and 1 ( generate ADTS header). Default is 0. Valid values are 0 (disable TNS) and 1 (enable TNS). Default is 1. + controls usage of noise filling in encoding. Default 0. + controls usage of complex prediction in encoding. Default is 0. is the framesize to be used. - For AOT 23, 39 (LD core coder profiles) valid values are 480 and 512. Default is 512. - For AOT 2, 5, 29 (LC core coder profiles) valid values are 960 and 1024. Default is 1024. - is the Audio object type - 2 for AAC-LC - 5 for HE-AACv1(Legacy SBR) - 23 for AAC-LD - 29 for HE-AACv2 - 39 for AAC-ELD - Default is 2 for AAC-LC. - Valid values are 0 (disable eSBR) and 1 (enable eSBR in HE-AACv1 encoding). Default is 0. - Enable use of full bandwidth of input. Valid values are 0(disable full bandwidth) and 1(enable full bandwidth). Default is 0. - is the maximum size of bit reservoir to be used. - Valid values are from -1 to 6144. -1 will omit use of bit reservoir. Default is 384. + For AOT 23, 39 (LD core coder profiles) valid values are 480 and 512. Default is 512. + For AOT 2, 5, 29 (LC core coder profiles) valid values are 960 and 1024. Default is 1024. + For AOT 42 (USAC profile) valid values are 768 and 1024. Default is 1024. + is the Audio object type. + 2 for AAC-LC + 5 for HE-AACv1(Legacy SBR) + 23 for AAC-LD + 29 for HE-AACv2 + 39 for AAC-ELD + 42 for USAC + Default is 2 for AAC-LC. + Valid values are 0 (disable eSBR) and 1 (enable eSBR). Default is 0 for HE-AACv1 profile (legacy SBR) and 1 for USAC profile. + Enable use of full bandwidth of input. Valid values are 0(disable full bandwidth) and 1(enable full bandwidth). Default is 0. + is the maximum size of bit reservoir to be used. Valid values are from -1 to 6144. -1 will omit use of bit reservoir. Default is 384. MPS tree config - 0 for '212' - 1 for '5151' - 2 for '5152' - 3 for '525' - Default '212' for stereo input and '5151' for 6ch input. + 0 for '212' + 1 for '5151' + 2 for '5152' + 3 for '525' + Default 0 for stereo input and 1 for 6ch input. + USAC encoding mode to be chose + 0 for 'usac_switched' + 1 for 'usac_fd' + 2 for 'usac_td' + Default 'usac_fd' + is the core coder framelength index for USAC encoder. + Valid values are 0, 1, 2, 3, 4. eSBR enabling is implicit + 0 - Core coder framelength of USAC is 768 and eSBR is disabled + 1 - Core coder framelength of USAC is 1024 and eSBR is disabled + 2 - Core coder framelength of USAC is 768 and eSBR ratio 8:3 + 3 - Core coder framelength of USAC is 1024 and eSBR ratio 2:1 + 4 - Core coder framelength of USAC is 1024 and eSBR ratio 4:1 + Valid values are 0 (disable PVC encoding) and 1 (enable PVC encoding). Default is 0. + Valid values are 0 (disable harmonic SBR) and 1 (enable harmonic SBR). Default is 0. + Valid values are 0 (disable high quality eSBR) and 1 (enable high quality eSBR). Default is 0. + Valid values are 0 (disable DRC encoding) and 1 (enable DRC encoding). Default is 0. + Valid values are 0 (disable inter-TES encoding) and 1 (enable inter-TES encoding). Default is 0. ``` Sample CLI: ``` diff --git a/decoder/drc_src/impd_drc_tables.h b/decoder/drc_src/impd_drc_tables.h deleted file mode 100644 index 7734763..0000000 --- a/decoder/drc_src/impd_drc_tables.h +++ /dev/null @@ -1,43 +0,0 @@ -/****************************************************************************** - * - * Copyright (C) 2015 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 -*/ -#ifndef IMPD_DRC_TABLES_H -#define IMPD_DRC_TABLES_H - -const ia_filter_bank_params_struct - normal_cross_freq[FILTER_BANK_PARAMETER_COUNT] = { - {2.0f / 1024.0f, 0.0000373252f, 0.9913600345f}, - {3.0f / 1024.0f, 0.0000836207f, 0.9870680830f}, - {4.0f / 1024.0f, 0.0001480220f, 0.9827947083f}, - {5.0f / 1024.0f, 0.0002302960f, 0.9785398263f}, - {6.0f / 1024.0f, 0.0003302134f, 0.9743033527f}, - {2.0f / 256.0f, 0.0005820761f, 0.9658852897f}, - {3.0f / 256.0f, 0.0012877837f, 0.9492662926f}, - {2.0f / 128.0f, 0.0022515827f, 0.9329321561f}, - {3.0f / 128.0f, 0.0049030350f, 0.9010958535f}, - {2.0f / 64.0f, 0.0084426929f, 0.8703307793f}, - {3.0f / 64.0f, 0.0178631928f, 0.8118317459f}, - {2.0f / 32.0f, 0.0299545822f, 0.7570763753f}, - {3.0f / 32.0f, 0.0604985076f, 0.6574551915f}, - {2.0f / 16.0f, 0.0976310729f, 0.5690355937f}, - {3.0f / 16.0f, 0.1866943331f, 0.4181633458f}, - {2.0f / 8.0f, 0.2928932188f, 0.2928932188f}, -}; - -#endif diff --git a/docs/LIBXAAC-Enc-API.pdf b/docs/LIBXAAC-Enc-API.pdf index cd09eac..e915e46 100644 Binary files a/docs/LIBXAAC-Enc-API.pdf and b/docs/LIBXAAC-Enc-API.pdf differ diff --git a/docs/LIBXAAC-Enc-GSG.pdf b/docs/LIBXAAC-Enc-GSG.pdf index 930b75e..008595b 100644 Binary files a/docs/LIBXAAC-Enc-GSG.pdf and b/docs/LIBXAAC-Enc-GSG.pdf differ diff --git a/encoder/drc_src/impd_drc_api.c b/encoder/drc_src/impd_drc_api.c new file mode 100644 index 0000000..1ae9f83 --- /dev/null +++ b/encoder/drc_src/impd_drc_api.c @@ -0,0 +1,210 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include "ixheaac_type_def.h" +#include "ixheaac_error_standards.h" +#include "ixheaace_error_codes.h" + +#include "iusace_bitbuffer.h" +#include "iusace_cnst.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" +#include "impd_drc_uni_drc_eq.h" +#include "impd_drc_uni_drc_filter_bank.h" +#include "impd_drc_gain_enc.h" +#include "impd_drc_struct_def.h" +#include "impd_drc_enc.h" + +static IA_ERRORCODE impd_drc_validate_drc_instructions( + ia_drc_uni_drc_config_struct *pstr_uni_drc_config) { + LOOPIDX i, j; + WORD32 profile_found = FALSE; + + for (i = 0; i < pstr_uni_drc_config->drc_instructions_uni_drc_count; i++) { + profile_found = FALSE; + for (j = 0; j < pstr_uni_drc_config->drc_coefficients_uni_drc_count; j++) { + if (pstr_uni_drc_config->str_drc_coefficients_uni_drc[j].drc_location == 1) { + profile_found = TRUE; + break; + } + } + if (pstr_uni_drc_config->uni_drc_config_ext_present && + pstr_uni_drc_config->str_uni_drc_config_ext.parametric_drc_present && + pstr_uni_drc_config->str_uni_drc_config_ext.str_drc_coeff_parametric_drc.drc_location == + 1) { + profile_found = TRUE; + } + if (profile_found == FALSE) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG; + } + } + + return IA_NO_ERROR; +} + +IA_ERRORCODE impd_drc_enc_init(VOID *pstr_drc_state, VOID *ptr_drc_scratch, + ia_drc_input_config *pstr_inp_config) { + IA_ERRORCODE err_code = IA_NO_ERROR; + WORD32 bit_count = 0; + ia_drc_enc_state *pstr_drc_state_local = pstr_drc_state; + +#ifdef ENABLE_SET_JUMP + jmp_buf drc_enc_init_jmp_buf; + err_code = setjmp(drc_enc_init_jmp_buf); + if (err_code != IA_NO_ERROR) { + return IA_EXHEAACE_INIT_FATAL_DRC_INSUFFICIENT_WRITE_BUFFER_SIZE; + } +#endif // ENABLE_SET_JUMP + + pstr_drc_state_local->drc_scratch_mem = ptr_drc_scratch; + pstr_drc_state_local->drc_scratch_used = 0; + + iusace_create_bit_buffer(&pstr_drc_state_local->str_bit_buf_cfg, + pstr_drc_state_local->bit_buf_base_cfg, + sizeof(pstr_drc_state_local->bit_buf_base_cfg), 1); + + iusace_create_bit_buffer(&pstr_drc_state_local->str_bit_buf_cfg_ext, + pstr_drc_state_local->bit_buf_base_cfg_ext, + sizeof(pstr_drc_state_local->bit_buf_base_cfg_ext), 1); + + iusace_create_bit_buffer(&pstr_drc_state_local->str_bit_buf_cfg_tmp, + pstr_drc_state_local->bit_buf_base_cfg_tmp, + sizeof(pstr_drc_state_local->bit_buf_base_cfg_tmp), 1); + + iusace_create_bit_buffer(&pstr_drc_state_local->str_bit_buf_out, + pstr_drc_state_local->bit_buf_base_out, + sizeof(pstr_drc_state_local->bit_buf_base_out), 1); + +#ifdef ENABLE_SET_JUMP + pstr_drc_state_local->str_bit_buf_cfg.impd_drc_jmp_buf = &drc_enc_init_jmp_buf; + pstr_drc_state_local->str_bit_buf_cfg_ext.impd_drc_jmp_buf = &drc_enc_init_jmp_buf; + pstr_drc_state_local->str_bit_buf_cfg_tmp.impd_drc_jmp_buf = &drc_enc_init_jmp_buf; + pstr_drc_state_local->str_bit_buf_out.impd_drc_jmp_buf = &drc_enc_init_jmp_buf; +#endif // ENABLE_SET_JUMP + + err_code = impd_drc_gain_enc_init( + &pstr_drc_state_local->str_gain_enc, &pstr_inp_config->str_uni_drc_config, + &pstr_inp_config->str_enc_loudness_info_set, pstr_inp_config->str_enc_params.frame_size, + pstr_inp_config->str_enc_params.sample_rate, pstr_inp_config->str_enc_params.delay_mode, + pstr_inp_config->str_enc_params.domain); + if (err_code & IA_FATAL_ERROR) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG; + } + + pstr_drc_state_local->str_enc_params = pstr_inp_config->str_enc_params; + pstr_drc_state_local->str_uni_drc_config = pstr_inp_config->str_uni_drc_config; + pstr_drc_state_local->str_enc_gain_extension = pstr_inp_config->str_enc_gain_extension; + + err_code = impd_drc_validate_drc_instructions(&pstr_inp_config->str_uni_drc_config); + if (err_code & IA_FATAL_ERROR) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG; + } + + err_code = impd_drc_write_uni_drc_config(pstr_drc_state_local, &bit_count); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + + pstr_drc_state_local->drc_config_data_size_bit = bit_count; + + return err_code; +} + +VOID impd_drc_enc(VOID *pstr_drc_state, FLOAT32 **pptr_input, UWORD32 inp_offset, + WORD32 *ptr_bits_written, VOID *pstr_scratch) { + LOOPIDX i, j, k; + WORD32 band_count = 0; + WORD32 stop_sub_band_index; + WORD32 num_bits_payload = 0; + UWORD8 is_fft_ready[MAX_NUM_CHANNELS] = {0}; + ia_drc_enc_state *pstr_drc_state_local = pstr_drc_state; + ia_drc_gain_enc_struct *pstr_gain_enc = &pstr_drc_state_local->str_gain_enc; + ia_drc_uni_drc_config_struct *pstr_uni_drc_config = &pstr_drc_state_local->str_uni_drc_config; + ia_drc_compand_struct *pstr_drc_compand; + ia_drc_stft_gain_calc_struct *pstr_drc_stft_gain_calc; + + if (pstr_drc_state_local->str_enc_params.gain_sequence_present) { + for (i = 0; i < MAX_DRC_COEFF_COUNT; i++) { + for (j = 0; j < GAIN_SET_COUNT_MAX; j++) { + pstr_drc_stft_gain_calc = &pstr_gain_enc->str_drc_stft_gain_handle[i][j][0]; + pstr_drc_compand = &pstr_gain_enc->str_drc_compand[i][j]; + if ((pstr_drc_compand->is_valid == 0) && (pstr_drc_stft_gain_calc->is_valid == 0)) { + break; + } + + if (pstr_drc_compand->is_valid == 0) { + if (is_fft_ready[pstr_drc_stft_gain_calc->ch_idx] == 0) { + impd_drc_stft_drc_convert_to_fd( + pstr_gain_enc, &pptr_input[pstr_drc_stft_gain_calc->ch_idx][inp_offset], + pstr_drc_stft_gain_calc->ch_idx, pstr_drc_state_local->str_enc_params.frame_size, + pstr_gain_enc->complex_fft_ptr[pstr_drc_stft_gain_calc->ch_idx], pstr_scratch); + is_fft_ready[pstr_drc_stft_gain_calc->ch_idx] = 1; + } + + for (k = 0; k < pstr_uni_drc_config->str_drc_coefficients_uni_drc[i] + .str_gain_set_params[j] + .band_count; + k++) { + if (k == pstr_uni_drc_config->str_drc_coefficients_uni_drc[i] + .str_gain_set_params[j] + .band_count - + 1) { + stop_sub_band_index = STFT256_HOP_SIZE - 1; + } else { + stop_sub_band_index = pstr_uni_drc_config->str_drc_coefficients_uni_drc[i] + .str_gain_set_params[j] + .gain_params[k + 1] + .start_sub_band_index - + 1; + } + + impd_drc_stft_drc_gain_calc_process( + pstr_gain_enc, i, j, k, + pstr_uni_drc_config->str_drc_coefficients_uni_drc[i] + .str_gain_set_params[j] + .gain_params[k] + .start_sub_band_index, + stop_sub_band_index, pstr_drc_state_local->str_enc_params.frame_size, + pstr_gain_enc->complex_fft_ptr[pstr_drc_stft_gain_calc->ch_idx], + pstr_drc_state_local->gain_buffer[band_count + k]); + } + } else { + impd_drc_td_drc_gain_calc_process(pstr_gain_enc, i, j, + pstr_drc_state_local->str_enc_params.frame_size, + &pptr_input[pstr_drc_compand->ch_idx][inp_offset], + pstr_drc_state_local->gain_buffer[band_count]); + } + + band_count += pstr_uni_drc_config->str_drc_coefficients_uni_drc[i] + .str_gain_set_params[j] + .band_count; + } + } + } + impd_drc_encode_uni_drc_gain(pstr_gain_enc, pstr_drc_state_local->gain_buffer[0], pstr_scratch); + + if (pstr_drc_state_local->is_first_drc_process_complete == 1) { + impd_drc_write_uni_drc_gain(pstr_drc_state_local, &num_bits_payload); + } + + *ptr_bits_written = num_bits_payload; +} diff --git a/encoder/drc_src/impd_drc_api.h b/encoder/drc_src/impd_drc_api.h new file mode 100644 index 0000000..51b71bc --- /dev/null +++ b/encoder/drc_src/impd_drc_api.h @@ -0,0 +1,43 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +typedef struct { + WORD32 frame_size; + WORD32 sample_rate; + WORD32 delay_mode; + WORD32 domain; + WORD32 parametric_drc_only; + WORD32 frame_count; + WORD32 gain_sequence_present; +} ia_drc_enc_params_struct; + +typedef struct { + ia_drc_enc_params_struct str_enc_params; + ia_drc_uni_drc_config_struct str_uni_drc_config; + ia_drc_loudness_info_set_struct str_enc_loudness_info_set; + ia_drc_uni_drc_gain_ext_struct str_enc_gain_extension; +} ia_drc_input_config; + +IA_ERRORCODE impd_drc_enc_init(VOID *pstr_drc_state, VOID *ptr_drc_scratch, + ia_drc_input_config *pstr_inp_config); + +VOID impd_drc_enc(VOID *pstr_drc_state, FLOAT32 **pptr_input, UWORD32 inp_offset, + WORD32 *ptr_bits_written, VOID *pstr_scratch); diff --git a/encoder/drc_src/impd_drc_common_enc.h b/encoder/drc_src/impd_drc_common_enc.h new file mode 100644 index 0000000..4086eba --- /dev/null +++ b/encoder/drc_src/impd_drc_common_enc.h @@ -0,0 +1,79 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +#define MAX_DRC_PAYLOAD_BYTES (2048) +#define MAX_SPEAKER_POS_COUNT (128) +#define MAX_DOWNMIX_COEFF_COUNT (32 * 32) +#define MAX_CHANNEL_COUNT (128) +#define MAX_BAND_COUNT (8) +#define MAX_SEQUENCE_COUNT (8) +#define MAX_MEASUREMENT_COUNT (16) +#define MAX_DOWNMIX_INSTRUCTION_COUNT (16) +#define MAX_DRC_COEFF_COUNT (8) +#define MAX_DRC_INSTRUCTIONS_COUNT (MAX_DOWNMIX_INSTRUCTION_COUNT + 16) +#define MAX_LOUDNESS_INFO_COUNT (MAX_DOWNMIX_INSTRUCTION_COUNT + 16) +#define MAX_AUDIO_CODEC_FRAME_SIZE (2048) +#define MAX_DRC_CODEC_FRAME_SIZE (MAX_AUDIO_CODEC_FRAME_SIZE / 8) +#define MAX_NODE_COUNT (MAX_DRC_CODEC_FRAME_SIZE) +#define MAX_CHANNEL_GROUP_COUNT (MAX_SEQUENCE_COUNT) +#define MAX_ADDITIONAL_DOWNMIX_ID (8) +#define DELAY_MODE_REGULAR_DELAY (0) +#define MAX_EXT_COUNT (2) + +#define UNIDRC_GAIN_EXT_TERM (0x0) +#define UNIDRC_LOUD_EXT_TERM (0x0) +#define UNIDRC_CONF_EXT_TERM (0x0) +#define UNIDRC_CONF_EXT_PARAM_DRC (0x1) +#define UNIDRC_CONF_EXT_V1 (0x2) +#define UNIDRC_LOUD_EXT_EQ (0x1) + +#define MAX_PARAM_DRC_INSTRUCTIONS_COUNT (8) + +#define PARAM_DRC_TYPE_FF (0x0) +#define MAX_PARAM_DRC_TYPE_FF_NODE_COUNT (9) + +#define PARAM_DRC_TYPE_LIM (0x1) +#define PARAM_DRC_TYPE_LIM_ATTACK_DEFAULT (5) + +#define SUBBAND_DOMAIN_MODE_OFF (0) +#define SUBBAND_DOMAIN_MODE_QMF64 (1) +#define SUBBAND_DOMAIN_MODE_QMF71 (2) +#define SUBBAND_DOMAIN_MODE_STFT256 (3) + +#define QMF64_AUDIO_CODEC_SUBBAND_COUNT (64) +#define QMF64_AUDIO_CODEC_SUBBAND_DOWNSAMPLING_FACTOR (64) + +#define QMF71_AUDIO_CODEC_SUBBAND_COUNT (71) +#define QMF71_AUDIO_CODEC_SUBBAND_DOWNSAMPLING_FACTOR (64) + +#define STFT256_AUDIO_CODEC_SUBBAND_COUNT (256) +#define STFT256_AUDIO_CODEC_SUBBAND_DOWNSAMPLING_FACTOR (256) + +#define TIME_DOMAIN (1) +#define SUBBAND_DOMAIN (2) +#define SLOPE_FACTOR_DB_TO_LINEAR (0.1151f) /* ln(10) / 20 */ + +#ifndef MIN +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif +#ifndef MAX +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif diff --git a/encoder/drc_src/impd_drc_enc.c b/encoder/drc_src/impd_drc_enc.c new file mode 100644 index 0000000..38db7c2 --- /dev/null +++ b/encoder/drc_src/impd_drc_enc.c @@ -0,0 +1,284 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include "ixheaac_type_def.h" +#include "ixheaac_error_standards.h" +#include "ixheaace_error_codes.h" + +#include "iusace_bitbuffer.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" +#include "impd_drc_uni_drc_eq.h" +#include "impd_drc_uni_drc_filter_bank.h" +#include "impd_drc_gain_enc.h" +#include "impd_drc_struct_def.h" +#include "impd_drc_enc.h" + +static VOID impd_drc_util_stft_read_gain_config( + ia_drc_stft_gain_calc_struct *pstr_stft_drc_gain_handle, WORD32 band_count, + ia_drc_gain_set_params_struct *str_gain_set_params) { + LOOPIDX i, j; + WORD32 num_points; + + for (i = 0; i < band_count; i++) { + num_points = str_gain_set_params->gain_params[i].nb_points; + pstr_stft_drc_gain_handle[i].nb_points = num_points; + for (j = 0; j < num_points; j++) { + pstr_stft_drc_gain_handle[i].str_segment[2 * (j + 1)].x = + str_gain_set_params->gain_params[i].gain_points[j].x; + pstr_stft_drc_gain_handle[i].str_segment[2 * (j + 1)].y = + str_gain_set_params->gain_params[i].gain_points[j].y; + } + + pstr_stft_drc_gain_handle[i].width_db = str_gain_set_params->gain_params[i].width; + pstr_stft_drc_gain_handle[i].attack_ms = str_gain_set_params->gain_params[i].attack; + pstr_stft_drc_gain_handle[i].release_ms = str_gain_set_params->gain_params[i].decay; + } +} + +static VOID impd_drc_util_td_read_gain_config( + ia_drc_compand_struct *pstr_drc_compand, ia_drc_gain_set_params_struct *str_gain_set_params) { + LOOPIDX idx; + WORD32 num_points; + + num_points = str_gain_set_params->gain_params[0].nb_points; + pstr_drc_compand->nb_points = num_points; + for (idx = 0; idx < num_points; idx++) { + pstr_drc_compand->str_segment[2 * (idx + 1)].x = + str_gain_set_params->gain_params[0].gain_points[idx].x; + pstr_drc_compand->str_segment[2 * (idx + 1)].y = + str_gain_set_params->gain_params[0].gain_points[idx].y; + } + + pstr_drc_compand->width_db = str_gain_set_params->gain_params[0].width; + pstr_drc_compand->str_channel_param.attack = str_gain_set_params->gain_params[0].attack; + pstr_drc_compand->str_channel_param.decay = str_gain_set_params->gain_params[0].decay; + + pstr_drc_compand->str_channel_param.attack /= 1000.0; + pstr_drc_compand->str_channel_param.decay /= 1000.0; +} + +IA_ERRORCODE impd_drc_gain_enc_init(ia_drc_gain_enc_struct *pstr_gain_enc, + ia_drc_uni_drc_config_struct *pstr_uni_drc_config, + ia_drc_loudness_info_set_struct *pstr_loudness_info_set, + const WORD32 frame_size, const WORD32 sample_rate, + const WORD32 delay_mode, const WORD32 domain) { + IA_ERRORCODE err_code = IA_NO_ERROR; + LOOPIDX i, j, k, l, m, ch; + WORD32 num_gain_values_max; + WORD32 params_found; + UWORD8 found_ch_idx; + UWORD32 ch_idx; + + ia_drc_uni_drc_config_ext_struct *pstr_uni_drc_config_ext = + &pstr_uni_drc_config->str_uni_drc_config_ext; + ia_drc_coefficients_uni_drc_struct *pstr_drc_coefficients_uni_drc = + &pstr_uni_drc_config->str_drc_coefficients_uni_drc[0]; + ia_drc_coefficients_uni_drc_struct *pstr_drc_coefficients_uni_drc_v1 = + &pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[0]; + + if (pstr_uni_drc_config_ext->drc_coefficients_uni_drc_v1_count <= 0) { + WORD32 all_band_gain_count = 0; + WORD32 gain_set_count = pstr_drc_coefficients_uni_drc->gain_set_count; + for (i = 0; i < gain_set_count; i++) { + all_band_gain_count += pstr_drc_coefficients_uni_drc->str_gain_set_params[i].band_count; + } + pstr_gain_enc->n_sequences = all_band_gain_count; + } else { + pstr_gain_enc->n_sequences = pstr_drc_coefficients_uni_drc_v1->gain_sequence_count; + } + + if (pstr_gain_enc->n_sequences > IMPD_DRCMAX_NSEQ) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_PARAM_OUT_OF_RANGE; + } + + if ((pstr_uni_drc_config_ext->drc_coefficients_uni_drc_v1_count > 0) && + (pstr_drc_coefficients_uni_drc_v1->drc_frame_size_present)) { + pstr_gain_enc->drc_frame_size = pstr_drc_coefficients_uni_drc_v1->drc_frame_size; + } else if ((pstr_uni_drc_config->drc_coefficients_uni_drc_count > 0) && + (pstr_drc_coefficients_uni_drc->drc_frame_size_present)) { + pstr_gain_enc->drc_frame_size = pstr_drc_coefficients_uni_drc->drc_frame_size; + } else { + pstr_gain_enc->drc_frame_size = frame_size; + } + + if (pstr_gain_enc->drc_frame_size > IMPD_DRCMAX_FRAMESIZE) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_PARAM_OUT_OF_RANGE; + } + if (pstr_gain_enc->drc_frame_size < 1) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG; + } + + if (!pstr_uni_drc_config->sample_rate_present) { + pstr_gain_enc->sample_rate = sample_rate; + } else { + pstr_gain_enc->sample_rate = pstr_uni_drc_config->sample_rate; + } + + pstr_gain_enc->domain = domain; + pstr_gain_enc->delay_mode = delay_mode; + pstr_gain_enc->delta_tmin_default = impd_drc_get_delta_t_min(pstr_gain_enc->sample_rate); + + if ((pstr_uni_drc_config_ext->drc_coefficients_uni_drc_v1_count > 0) && + (pstr_drc_coefficients_uni_drc_v1->str_gain_set_params[0].time_delta_min_present == 1)) { + pstr_gain_enc->delta_tmin = + pstr_drc_coefficients_uni_drc_v1->str_gain_set_params[0].delta_tmin; + } else if ((pstr_uni_drc_config->drc_coefficients_uni_drc_count > 0) && + (pstr_drc_coefficients_uni_drc->str_gain_set_params[0].time_delta_min_present == + 1)) { + pstr_gain_enc->delta_tmin = pstr_drc_coefficients_uni_drc->str_gain_set_params[0].delta_tmin; + } else { + pstr_gain_enc->delta_tmin = impd_drc_get_delta_t_min(pstr_gain_enc->sample_rate); + } + + num_gain_values_max = pstr_gain_enc->drc_frame_size / pstr_gain_enc->delta_tmin; + pstr_gain_enc->base_ch_count = pstr_uni_drc_config->str_channel_layout.base_ch_count; + + memcpy(&pstr_gain_enc->str_uni_drc_config, pstr_uni_drc_config, + sizeof(ia_drc_uni_drc_config_struct)); + memcpy(&pstr_gain_enc->str_loudness_info_set, pstr_loudness_info_set, + sizeof(ia_drc_loudness_info_set_struct)); + + k = 0; + if (pstr_uni_drc_config->drc_coefficients_uni_drc_count > 0) { + for (j = 0; j < pstr_drc_coefficients_uni_drc->gain_set_count; j++) { + ch_idx = 0; + found_ch_idx = 0; + ia_drc_gain_set_params_struct *pstr_gain_set_params = + &pstr_drc_coefficients_uni_drc->str_gain_set_params[j]; + + for (m = 0; m < pstr_uni_drc_config->drc_instructions_uni_drc_count; m++) { + if (pstr_uni_drc_config->str_drc_instructions_uni_drc[m].drc_location == + pstr_drc_coefficients_uni_drc->drc_location) { + for (ch = 0; ch < MAX_CHANNEL_COUNT; ch++) { + if (pstr_uni_drc_config->str_drc_instructions_uni_drc[m].gain_set_index[ch] == j) { + ch_idx = ch; + found_ch_idx = 1; + break; + } + } + } + if (found_ch_idx) { + break; + } + } + + if (pstr_gain_set_params->band_count > 1) { + impd_drc_util_stft_read_gain_config(pstr_gain_enc->str_drc_stft_gain_handle[0][j], + pstr_gain_set_params->band_count, + pstr_gain_set_params); + + for (l = 0; l < pstr_gain_set_params->band_count; l++) { + err_code = impd_drc_stft_drc_gain_calc_init(pstr_gain_enc, 0, j, l); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + pstr_gain_enc->str_drc_stft_gain_handle[0][j][l].ch_idx = ch_idx; + pstr_gain_enc->str_drc_stft_gain_handle[0][j][l].is_valid = 1; + } + } else if (pstr_gain_set_params->band_count == 1) { + impd_drc_util_td_read_gain_config(&pstr_gain_enc->str_drc_compand[0][j], + pstr_gain_set_params); + + pstr_gain_enc->str_drc_compand[0][j].initial_volume = 0.0f; + + err_code = impd_drc_td_drc_gain_calc_init(pstr_gain_enc, 0, j); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + pstr_gain_enc->str_drc_compand[0][j].ch_idx = ch_idx; + pstr_gain_enc->str_drc_compand[0][j].is_valid = 1; + } + + for (l = 0; l < pstr_gain_set_params->band_count; l++) { + pstr_gain_enc->str_drc_gain_seq_buf[k].str_drc_group.n_gain_values = 1; + pstr_gain_enc->str_drc_gain_seq_buf[k].str_gain_set_params = + pstr_drc_coefficients_uni_drc->str_gain_set_params[j]; + k++; + } + } + } + if (pstr_uni_drc_config_ext->drc_coefficients_uni_drc_v1_count > 0) { + for (i = 0; i < pstr_gain_enc->n_sequences; i++) { + params_found = 0; + + for (j = 0; j < pstr_drc_coefficients_uni_drc_v1->gain_set_count; j++) { + for (l = 0; l < pstr_drc_coefficients_uni_drc_v1->str_gain_set_params[j].band_count; + l++) { + if (i == pstr_drc_coefficients_uni_drc_v1->str_gain_set_params[j] + .gain_params[l] + .gain_sequence_index) { + pstr_gain_enc->str_drc_gain_seq_buf[i].str_drc_group.n_gain_values = 1; + pstr_gain_enc->str_drc_gain_seq_buf[i].str_gain_set_params = + pstr_drc_coefficients_uni_drc_v1->str_gain_set_params[j]; + params_found = 1; + } + if (params_found == 1) { + break; + } + } + if (params_found == 1) { + break; + } + } + } + } + + impd_drc_generate_delta_time_code_table(num_gain_values_max, + pstr_gain_enc->str_delta_time_code_table); + + for (i = num_gain_values_max - 1; i >= 0; i--) { + pstr_gain_enc->delta_time_quant_table[i] = pstr_gain_enc->delta_tmin * (i + 1); + } + + return err_code; +} + +VOID impd_drc_encode_uni_drc_gain(ia_drc_gain_enc_struct *pstr_gain_enc, FLOAT32 *ptr_gain_buffer, + VOID *pstr_scratch) { + LOOPIDX idx; + + for (idx = 0; idx < pstr_gain_enc->n_sequences; idx++) { + impd_drc_quantize_and_encode_drc_gain( + pstr_gain_enc, &ptr_gain_buffer[idx * MAX_DRC_FRAME_SIZE], + &(pstr_gain_enc->drc_gain_per_sample_with_prev_frame[idx][0]), + pstr_gain_enc->str_delta_time_code_table, &(pstr_gain_enc->str_drc_gain_seq_buf[idx]), + pstr_scratch); + } +} + +WORD32 impd_drc_get_delta_t_min(const WORD32 sample_rate) { + WORD32 lower_bound; + WORD32 result = 1; + WORD32 sample_rate_local = sample_rate; + + if (sample_rate_local < 1000) { + sample_rate_local = 1000; + } + lower_bound = (WORD32)((0.0005f * sample_rate_local) + 0.5f); + + while (result <= lower_bound) { + result = result << 1; + } + return result; +} diff --git a/encoder/drc_src/impd_drc_enc.h b/encoder/drc_src/impd_drc_enc.h new file mode 100644 index 0000000..e700125 --- /dev/null +++ b/encoder/drc_src/impd_drc_enc.h @@ -0,0 +1,40 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +IA_ERRORCODE impd_drc_gain_enc_init(ia_drc_gain_enc_struct *pstr_gain_enc, + ia_drc_uni_drc_config_struct *pstr_uni_drc_config, + ia_drc_loudness_info_set_struct *pstr_loudness_info_set, + const WORD32 frame_size, const WORD32 sample_rate, + const WORD32 delay_mode, const WORD32 domain); + +WORD32 impd_drc_get_delta_t_min(const WORD32 sample_rate); + +VOID impd_drc_encode_uni_drc_gain(ia_drc_gain_enc_struct *pstr_gain_enc, FLOAT32 *ptr_gain_buffer, + VOID *pstr_scratch); + +IA_ERRORCODE impd_drc_write_loudness_info_set_extension( + ia_drc_enc_state *pstr_drc_state, ia_bit_buf_struct *it_bit_buf, + ia_drc_loudness_info_set_extension_struct *pstr_loudness_info_set_extension, + WORD32 *ptr_bit_cnt); + +IA_ERRORCODE impd_drc_write_uni_drc_config(ia_drc_enc_state *pstr_drc_state, WORD32 *ptr_bit_cnt); + +VOID impd_drc_write_uni_drc_gain(ia_drc_enc_state *pstr_drc_state, WORD32 *ptr_bit_cnt); diff --git a/encoder/drc_src/impd_drc_gain_calculator.c b/encoder/drc_src/impd_drc_gain_calculator.c new file mode 100644 index 0000000..24514c3 --- /dev/null +++ b/encoder/drc_src/impd_drc_gain_calculator.c @@ -0,0 +1,518 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ +#include +#include "ixheaac_type_def.h" +#include "ixheaac_error_standards.h" +#include "ixheaace_error_codes.h" + +#include "iusace_cnst.h" +#include "iusace_block_switch_const.h" +#include "iusace_bitbuffer.h" + +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" + +#include "iusace_tns_usac.h" +#include "iusace_psy_mod.h" +#include "ixheaace_sbr_header.h" +#include "ixheaace_config.h" +#include "iusace_config.h" + +#include "iusace_rom.h" +#include "iusace_fft.h" + +#include "impd_drc_uni_drc_eq.h" +#include "impd_drc_uni_drc_filter_bank.h" +#include "impd_drc_gain_enc.h" +#include "impd_drc_struct_def.h" +#include "impd_drc_enc.h" + +static VOID impd_drc_compand_update_volume(ia_drc_compand_chan_param_struct *pstr_channel_param, + FLOAT64 in_value) { + FLOAT64 delta = in_value - pstr_channel_param->volume; + + if (delta <= 0.0) { + pstr_channel_param->volume += delta * pstr_channel_param->decay; + } else { + pstr_channel_param->volume += delta * pstr_channel_param->attack; + } +} + +static FLOAT64 impd_drc_compand_get_volume(ia_drc_compand_struct *pstr_drc_compand, + FLOAT64 in_lin) { + ULOOPIDX idx; + FLOAT64 in_log, out_log; + ia_drc_compand_segment_struct *pstr_compand_segment; + + if (in_lin < pstr_drc_compand->in_min_lin) { + return pstr_drc_compand->out_min_lin; + } + + in_log = log(in_lin); + + for (idx = 1; idx < pstr_drc_compand->nb_segments; idx++) { + if (in_log <= pstr_drc_compand->str_segment[idx].x) { + break; + } + } + + pstr_compand_segment = &pstr_drc_compand->str_segment[idx - 1]; + in_log -= pstr_compand_segment->x; + out_log = pstr_compand_segment->y + + in_log * (pstr_compand_segment->a * in_log + pstr_compand_segment->b); + + return exp(out_log); +} + +VOID impd_drc_td_drc_gain_calc_process(ia_drc_gain_enc_struct *pstr_drc_gain_enc, + WORD32 drc_coefficients_uni_drc_idx, WORD32 gain_set_idx, + WORD32 num_samples, FLOAT32 *in_buff, FLOAT32 *out_buff) { + LOOPIDX idx; + FLOAT64 gain; + ia_drc_compand_chan_param_struct *pstr_channel_param; + ia_drc_compand_struct *pstr_drc_compand = + &pstr_drc_gain_enc->str_drc_compand[drc_coefficients_uni_drc_idx][gain_set_idx]; + + pstr_channel_param = &pstr_drc_compand->str_channel_param; + + for (idx = 0; idx < num_samples; idx++) { + impd_drc_compand_update_volume(pstr_channel_param, fabs((FLOAT64)in_buff[idx] / 32768.0)); + + gain = impd_drc_compand_get_volume(pstr_drc_compand, pstr_channel_param->volume); + out_buff[idx] = (FLOAT32)(20.0 * log10(gain)); + } +} + +IA_ERRORCODE impd_drc_td_drc_gain_calc_init(ia_drc_gain_enc_struct *pstr_drc_gain_enc, + WORD32 drc_coefficients_uni_drc_idx, + WORD32 gain_set_idx) { + ULOOPIDX i, j; + UWORD32 num_points; + FLOAT64 g1, g2; + FLOAT64 x, y, cx, cy, r; + FLOAT64 inp_1, inp_2, out_1, out_2, theta, length, radius; + ia_drc_compand_struct *pstr_drc_compand; + ia_drc_compand_chan_param_struct *pstr_chan_param; + + if ((drc_coefficients_uni_drc_idx >= MAX_DRC_COEFF_COUNT) || + (gain_set_idx >= GAIN_SET_COUNT_MAX)) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_COMPAND_FAILED; + } + + pstr_drc_compand = + &pstr_drc_gain_enc->str_drc_compand[drc_coefficients_uni_drc_idx][gain_set_idx]; + + pstr_drc_compand->nb_segments = (pstr_drc_compand->nb_points + 4) * 2; + + for (i = 0; i < pstr_drc_compand->nb_points; i++) { + if (i && pstr_drc_compand->str_segment[2 * ((i - 1) + 1)].x > + pstr_drc_compand->str_segment[2 * ((i) + 1)].x) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_COMPAND_FAILED; + } + pstr_drc_compand->str_segment[2 * (i + 1)].y -= pstr_drc_compand->str_segment[2 * (i + 1)].x; + } + num_points = pstr_drc_compand->nb_points; + + if (num_points == 0 || pstr_drc_compand->str_segment[2 * ((num_points - 1) + 1)].x) { + num_points++; + } + + pstr_drc_compand->str_segment[0].x = + pstr_drc_compand->str_segment[2].x - 2 * pstr_drc_compand->width_db; + pstr_drc_compand->str_segment[0].y = pstr_drc_compand->str_segment[2].y; + num_points++; + + radius = pstr_drc_compand->width_db * M_LN10_DIV_20; + + for (i = 2; i < num_points; i++) { + g1 = (pstr_drc_compand->str_segment[2 * (i - 1)].y - + pstr_drc_compand->str_segment[2 * (i - 2)].y) * + (pstr_drc_compand->str_segment[2 * i].x - pstr_drc_compand->str_segment[2 * (i - 1)].x); + g2 = (pstr_drc_compand->str_segment[2 * i].y - pstr_drc_compand->str_segment[2 * (i - 1)].y) * + (pstr_drc_compand->str_segment[2 * (i - 1)].x - + pstr_drc_compand->str_segment[2 * (i - 2)].x); + + if (fabs(g1 - g2)) { + continue; + } + num_points--; + + for (j = --i; j < num_points; j++) { + pstr_drc_compand->str_segment[2 * j] = pstr_drc_compand->str_segment[2 * (j + 1)]; + } + } + + for (i = 0; i < pstr_drc_compand->nb_segments; i += 2) { + pstr_drc_compand->str_segment[i].y += pstr_drc_compand->gain_db; + pstr_drc_compand->str_segment[i].x *= M_LN10_DIV_20; + pstr_drc_compand->str_segment[i].y *= M_LN10_DIV_20; + } + + for (i = 4; i < pstr_drc_compand->nb_segments; i += 2) { + pstr_drc_compand->str_segment[i - 4].a = 0; + pstr_drc_compand->str_segment[i - 4].b = + (pstr_drc_compand->str_segment[i - 2].y - pstr_drc_compand->str_segment[i - 4].y) / + (pstr_drc_compand->str_segment[i - 2].x - pstr_drc_compand->str_segment[i - 4].x); + + pstr_drc_compand->str_segment[i - 2].a = 0; + pstr_drc_compand->str_segment[i - 2].b = + (pstr_drc_compand->str_segment[i].y - pstr_drc_compand->str_segment[i - 2].y) / + (pstr_drc_compand->str_segment[i].x - pstr_drc_compand->str_segment[i - 2].x); + + theta = + atan2(pstr_drc_compand->str_segment[i - 2].y - pstr_drc_compand->str_segment[i - 4].y, + pstr_drc_compand->str_segment[i - 2].x - pstr_drc_compand->str_segment[i - 4].x); + length = + hypot(pstr_drc_compand->str_segment[i - 2].x - pstr_drc_compand->str_segment[i - 4].x, + pstr_drc_compand->str_segment[i - 2].y - pstr_drc_compand->str_segment[i - 4].y); + + r = MIN(radius, length); + pstr_drc_compand->str_segment[i - 3].x = + pstr_drc_compand->str_segment[i - 2].x - r * cos(theta); + pstr_drc_compand->str_segment[i - 3].y = + pstr_drc_compand->str_segment[i - 2].y - r * sin(theta); + + theta = + atan2(pstr_drc_compand->str_segment[i].y - pstr_drc_compand->str_segment[i - 2].y, + pstr_drc_compand->str_segment[i - 0].x - pstr_drc_compand->str_segment[i - 2].x); + length = hypot(pstr_drc_compand->str_segment[i].x - pstr_drc_compand->str_segment[i - 2].x, + pstr_drc_compand->str_segment[i].y - pstr_drc_compand->str_segment[i - 2].y); + + r = MIN(radius, length / 2); + x = pstr_drc_compand->str_segment[i - 2].x + r * cos(theta); + y = pstr_drc_compand->str_segment[i - 2].y + r * sin(theta); + + cx = + (pstr_drc_compand->str_segment[i - 3].x + pstr_drc_compand->str_segment[i - 2].x + x) / 3; + cy = + (pstr_drc_compand->str_segment[i - 3].y + pstr_drc_compand->str_segment[i - 2].y + y) / 3; + + pstr_drc_compand->str_segment[i - 2].x = x; + pstr_drc_compand->str_segment[i - 2].y = y; + + inp_1 = cx - pstr_drc_compand->str_segment[i - 3].x; + out_1 = cy - pstr_drc_compand->str_segment[i - 3].y; + inp_2 = pstr_drc_compand->str_segment[i - 2].x - pstr_drc_compand->str_segment[i - 3].x; + out_2 = pstr_drc_compand->str_segment[i - 2].y - pstr_drc_compand->str_segment[i - 3].y; + pstr_drc_compand->str_segment[i - 3].a = (out_2 / inp_2 - out_1 / inp_1) / (inp_2 - inp_1); + pstr_drc_compand->str_segment[i - 3].b = + out_1 / inp_1 - pstr_drc_compand->str_segment[i - 3].a * inp_1; + } + pstr_drc_compand->str_segment[i - 3].x = 0; + pstr_drc_compand->str_segment[i - 3].y = pstr_drc_compand->str_segment[i - 3].y; + + pstr_drc_compand->in_min_lin = exp(pstr_drc_compand->str_segment[1].x); + pstr_drc_compand->out_min_lin = exp(pstr_drc_compand->str_segment[1].y); + + pstr_chan_param = &pstr_drc_compand->str_channel_param; + + if (pstr_chan_param->attack < 1.0 / pstr_drc_gain_enc->sample_rate) { + pstr_chan_param->attack = 1.0; + } else { + pstr_chan_param->attack = + 1.0 - exp(-1.0 / (pstr_drc_gain_enc->sample_rate * pstr_chan_param->attack)); + } + + if (pstr_chan_param->decay < 1.0 / pstr_drc_gain_enc->sample_rate) { + pstr_chan_param->decay = 1.0; + } else { + pstr_chan_param->decay = + 1.0 - exp(-1.0 / (pstr_drc_gain_enc->sample_rate * pstr_chan_param->decay)); + } + pstr_chan_param->volume = EXP10(pstr_drc_compand->initial_volume / 20); + + return IA_NO_ERROR; +} + +static FLOAT32 impd_drc_stft_drc_compand_get_volume( + ia_drc_stft_gain_calc_struct *pstr_drc_stft_gain_handle, FLOAT32 in_db) { + ULOOPIDX idx; + FLOAT32 in_log, out_log; + ia_drc_compand_segment_struct *pstr_compand_segment; + + if (in_db < pstr_drc_stft_gain_handle->in_min_db) { + return pstr_drc_stft_gain_handle->out_min_db; + } + + in_log = (FLOAT32)(in_db * M_LN10_DIV_20); + + for (idx = 1; idx < pstr_drc_stft_gain_handle->nb_segments; idx++) { + if (in_log <= pstr_drc_stft_gain_handle->str_segment[idx].x) { + break; + } + } + + pstr_compand_segment = &pstr_drc_stft_gain_handle->str_segment[idx - 1]; + in_log -= (FLOAT32)(pstr_compand_segment->x); + out_log = (FLOAT32)(pstr_compand_segment->y + + in_log * (pstr_compand_segment->a * in_log + pstr_compand_segment->b)); + + return (FLOAT32)(out_log * M_LOG10_E * 20.0f); +} + +VOID impd_drc_stft_drc_gain_calc_process(ia_drc_gain_enc_struct *pstr_drc_gain_enc, + WORD32 drc_coefficients_uni_drc_idx, WORD32 gain_set_idx, + WORD32 band_idx, WORD32 start_sub_band_index, + WORD32 stop_sub_band_index, UWORD32 num_frames, + FLOAT32 *in_buff, FLOAT32 *gain_values) { + ULOOPIDX idx; + LOOPIDX band; + FLOAT32 xg, xl, yl, cdb; + FLOAT32 in_real, in_imag; + FLOAT32 abs_val_sqr; + UWORD32 num_time_slot = num_frames / STFT256_HOP_SIZE; + + ia_drc_stft_gain_calc_struct *pstr_drc_stft_gain_handle = + &pstr_drc_gain_enc + ->str_drc_stft_gain_handle[drc_coefficients_uni_drc_idx][gain_set_idx][band_idx]; + + for (idx = 0; idx < num_time_slot; idx++) { + abs_val_sqr = 0.0f; + for (band = start_sub_band_index; band <= stop_sub_band_index; band++) { + in_imag = in_buff[((idx * STFT256_HOP_SIZE + band) << 1) + 1]; + in_real = in_buff[(idx * STFT256_HOP_SIZE + band) << 1]; + + abs_val_sqr += sqrtf(powf(in_real, 2.0f) + powf(in_imag, 2.0f)); + } + + abs_val_sqr /= (FLOAT32)((stop_sub_band_index - start_sub_band_index + 1) << 4); + + abs_val_sqr = powf(abs_val_sqr, 2.0f); + xg = 10.0f * log10f((abs_val_sqr) + 2e-13f); + + xl = -impd_drc_stft_drc_compand_get_volume(pstr_drc_stft_gain_handle, xg); + + if (xl > pstr_drc_stft_gain_handle->yl_z1[band]) { + yl = (pstr_drc_stft_gain_handle->alpha_a * pstr_drc_stft_gain_handle->yl_z1[band]) + + ((1.0f - pstr_drc_stft_gain_handle->alpha_a) * xl); + } else { + yl = (pstr_drc_stft_gain_handle->alpha_r * pstr_drc_stft_gain_handle->yl_z1[band]) + + ((1.0f - pstr_drc_stft_gain_handle->alpha_r) * xl); + } + + pstr_drc_stft_gain_handle->yl_z1[band] = yl; + cdb = -yl; + cdb = MAX(IMPD_DRCSPECTRAL_FLOOR, (powf(10.0f, cdb / 20.0f))); + cdb = 20.0f * log10f(cdb); + + for (band = 0; band < STFT256_HOP_SIZE; band++) { + gain_values[idx * STFT256_HOP_SIZE + band] = cdb; + } + } +} + +IA_ERRORCODE impd_drc_stft_drc_gain_calc_init(ia_drc_gain_enc_struct *pstr_drc_gain_enc, + WORD32 drc_coefficients_uni_drc_idx, + WORD32 gain_set_idx, WORD32 band_idx) { + ULOOPIDX i, j; + UWORD32 num_points; + FLOAT32 width_e; + FLOAT64 g1, g2; + FLOAT64 x, y, cx, cy, r; + FLOAT64 inp_1, inp_2, out_1, out_2, theta, len; + ia_drc_compand_chan_param_struct *pstr_chan_param; + ia_drc_stft_gain_calc_struct *pstr_drc_stft_gain_handle; + + if ((drc_coefficients_uni_drc_idx >= MAX_DRC_COEFF_COUNT) || + (gain_set_idx >= GAIN_SET_COUNT_MAX) || (band_idx >= MAX_BAND_COUNT)) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_COMPAND_FAILED; + } + + pstr_drc_stft_gain_handle = + &pstr_drc_gain_enc + ->str_drc_stft_gain_handle[drc_coefficients_uni_drc_idx][gain_set_idx][band_idx]; + + width_e = (FLOAT32)(pstr_drc_stft_gain_handle->width_db * M_LN10_DIV_20); + + pstr_drc_stft_gain_handle->nb_segments = (pstr_drc_stft_gain_handle->nb_points + 4) * 2; + + for (i = 0; i < pstr_drc_stft_gain_handle->nb_points; i++) { + if (i && pstr_drc_stft_gain_handle->str_segment[2 * ((i - 1) + 1)].x > + pstr_drc_stft_gain_handle->str_segment[2 * (i + 1)].x) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_COMPAND_FAILED; + } + pstr_drc_stft_gain_handle->str_segment[2 * (i + 1)].y -= + pstr_drc_stft_gain_handle->str_segment[2 * (i + 1)].x; + } + num_points = pstr_drc_stft_gain_handle->nb_points; + + if (num_points == 0 || pstr_drc_stft_gain_handle->str_segment[2 * ((num_points - 1) + 1)].x) { + num_points++; + } + + pstr_drc_stft_gain_handle->str_segment[0].x = + pstr_drc_stft_gain_handle->str_segment[2].x - pstr_drc_stft_gain_handle->width_db; + pstr_drc_stft_gain_handle->str_segment[0].y = pstr_drc_stft_gain_handle->str_segment[2].y; + num_points++; + + for (i = 2; i < num_points; i++) { + g1 = (pstr_drc_stft_gain_handle->str_segment[2 * (i - 1)].y - + pstr_drc_stft_gain_handle->str_segment[2 * (i - 2)].y) * + (pstr_drc_stft_gain_handle->str_segment[2 * i].x - + pstr_drc_stft_gain_handle->str_segment[2 * (i - 1)].x); + g2 = (pstr_drc_stft_gain_handle->str_segment[2 * i].y - + pstr_drc_stft_gain_handle->str_segment[2 * (i - 1)].y) * + (pstr_drc_stft_gain_handle->str_segment[2 * (i - 1)].x - + pstr_drc_stft_gain_handle->str_segment[2 * (i - 2)].x); + + if (fabs(g1 - g2)) { + continue; + } + num_points--; + + for (j = --i; j < num_points; j++) { + pstr_drc_stft_gain_handle->str_segment[2 * j] = + pstr_drc_stft_gain_handle->str_segment[2 * (j + 1)]; + } + } + + for (i = 0; i < pstr_drc_stft_gain_handle->nb_segments; i += 2) { + pstr_drc_stft_gain_handle->str_segment[i].y += pstr_drc_stft_gain_handle->gain_db; + pstr_drc_stft_gain_handle->str_segment[i].x *= M_LN10_DIV_20; + pstr_drc_stft_gain_handle->str_segment[i].y *= M_LN10_DIV_20; + } + + for (i = 4; i < pstr_drc_stft_gain_handle->nb_segments; i += 2) { + pstr_drc_stft_gain_handle->str_segment[i - 4].a = 0; + pstr_drc_stft_gain_handle->str_segment[i - 4].b = + (pstr_drc_stft_gain_handle->str_segment[i - 2].y - + pstr_drc_stft_gain_handle->str_segment[i - 4].y) / + (pstr_drc_stft_gain_handle->str_segment[i - 2].x - + pstr_drc_stft_gain_handle->str_segment[i - 4].x); + + pstr_drc_stft_gain_handle->str_segment[i - 2].a = 0; + pstr_drc_stft_gain_handle->str_segment[i - 2].b = + (pstr_drc_stft_gain_handle->str_segment[i].y - + pstr_drc_stft_gain_handle->str_segment[i - 2].y) / + (pstr_drc_stft_gain_handle->str_segment[i].x - + pstr_drc_stft_gain_handle->str_segment[i - 2].x); + + theta = atan2(pstr_drc_stft_gain_handle->str_segment[i - 2].y - + pstr_drc_stft_gain_handle->str_segment[i - 4].y, + pstr_drc_stft_gain_handle->str_segment[i - 2].x - + pstr_drc_stft_gain_handle->str_segment[i - 4].x); + len = hypot(pstr_drc_stft_gain_handle->str_segment[i - 2].x - + pstr_drc_stft_gain_handle->str_segment[i - 4].x, + pstr_drc_stft_gain_handle->str_segment[i - 2].y - + pstr_drc_stft_gain_handle->str_segment[i - 4].y); + r = MIN(width_e / (2.0f * cos(theta)), len); + pstr_drc_stft_gain_handle->str_segment[i - 3].x = + pstr_drc_stft_gain_handle->str_segment[i - 2].x - r * cos(theta); + pstr_drc_stft_gain_handle->str_segment[i - 3].y = + pstr_drc_stft_gain_handle->str_segment[i - 2].y - r * sin(theta); + + theta = atan2(pstr_drc_stft_gain_handle->str_segment[i].y - + pstr_drc_stft_gain_handle->str_segment[i - 2].y, + pstr_drc_stft_gain_handle->str_segment[i].x - + pstr_drc_stft_gain_handle->str_segment[i - 2].x); + len = hypot(pstr_drc_stft_gain_handle->str_segment[i].x - + pstr_drc_stft_gain_handle->str_segment[i - 2].x, + pstr_drc_stft_gain_handle->str_segment[i].y - + pstr_drc_stft_gain_handle->str_segment[i - 2].y); + r = MIN(width_e / (2.0f * cos(theta)), len / 2); + x = pstr_drc_stft_gain_handle->str_segment[i - 2].x + r * cos(theta); + y = pstr_drc_stft_gain_handle->str_segment[i - 2].y + r * sin(theta); + + cx = (pstr_drc_stft_gain_handle->str_segment[i - 3].x + + pstr_drc_stft_gain_handle->str_segment[i - 2].x + x) / + 3; + cy = (pstr_drc_stft_gain_handle->str_segment[i - 3].y + + pstr_drc_stft_gain_handle->str_segment[i - 2].y + y) / + 3; + + pstr_drc_stft_gain_handle->str_segment[i - 2].x = x; + pstr_drc_stft_gain_handle->str_segment[i - 2].y = y; + + inp_1 = cx - pstr_drc_stft_gain_handle->str_segment[i - 3].x; + out_1 = cy - pstr_drc_stft_gain_handle->str_segment[i - 3].y; + inp_2 = pstr_drc_stft_gain_handle->str_segment[i - 2].x - + pstr_drc_stft_gain_handle->str_segment[i - 3].x; + out_2 = pstr_drc_stft_gain_handle->str_segment[i - 2].y - + pstr_drc_stft_gain_handle->str_segment[i - 3].y; + pstr_drc_stft_gain_handle->str_segment[i - 3].a = + (out_2 / inp_2 - out_1 / inp_1) / (inp_2 - inp_1); + pstr_drc_stft_gain_handle->str_segment[i - 3].b = + out_1 / inp_1 - pstr_drc_stft_gain_handle->str_segment[i - 3].a * inp_1; + } + pstr_drc_stft_gain_handle->str_segment[i - 3].x = 0; + pstr_drc_stft_gain_handle->str_segment[i - 3].y = + pstr_drc_stft_gain_handle->str_segment[i - 2].y; + + pstr_drc_stft_gain_handle->in_min_db = + (FLOAT32)(pstr_drc_stft_gain_handle->str_segment[1].x * M_LOG10_E * 20.0f); + pstr_drc_stft_gain_handle->out_min_db = + (FLOAT32)(pstr_drc_stft_gain_handle->str_segment[1].y * M_LOG10_E * 20.0f); + + pstr_chan_param = &pstr_drc_stft_gain_handle->str_channel_param; + + pstr_chan_param->volume = EXP10(pstr_drc_stft_gain_handle->initial_volume / 20.0f); + + for (i = 0; i < STFT256_HOP_SIZE; i++) { + pstr_drc_stft_gain_handle->yl_z1[i] = 0.0f; + } + + pstr_drc_stft_gain_handle->alpha_a = + expf(-1.0f / ((pstr_drc_stft_gain_handle->attack_ms / (FLOAT32)STFT256_HOP_SIZE) * + (FLOAT32)pstr_drc_gain_enc->sample_rate * 0.001f)); + + pstr_drc_stft_gain_handle->alpha_r = + expf(-1.0f / ((pstr_drc_stft_gain_handle->release_ms / (FLOAT32)STFT256_HOP_SIZE) * + (FLOAT32)pstr_drc_gain_enc->sample_rate * 0.001f)); + + return IA_NO_ERROR; +} + +VOID impd_drc_stft_drc_convert_to_fd(ia_drc_gain_enc_struct *pstr_drc_gain_enc, + FLOAT32 *ptr_input, UWORD32 ch_idx, UWORD32 frame_size, + FLOAT32 *ptr_output, VOID *pstr_scratch) { + ULOOPIDX i, j; + UWORD32 num_time_slot = frame_size / STFT256_HOP_SIZE; + FLOAT32 time_sample_vector; + iusace_scratch_mem *ptr_scratch = (iusace_scratch_mem *)(pstr_scratch); + pFLOAT32 scratch_buff = ptr_scratch->ptr_drc_scratch_buf; + + for (i = 0; i < num_time_slot; i++) { + for (j = 0; j < STFT256_HOP_SIZE; j++) { + time_sample_vector = (FLOAT32)(ptr_input[i * STFT256_HOP_SIZE + j] / (32768.0)); + + scratch_buff[(j << 1)] = + (FLOAT32)(pstr_drc_gain_enc->stft_tmp_in_buf_time[ch_idx][j] * iusace_sine_win_256[j]); + scratch_buff[(j << 1) + 1] = 0.0f; + + scratch_buff[(STFT256_HOP_SIZE + j) << 1] = + (FLOAT32)(iusace_sine_win_256[STFT256_HOP_SIZE - 1 - j] * time_sample_vector); + scratch_buff[((STFT256_HOP_SIZE + j) << 1) + 1] = 0.0f; + + pstr_drc_gain_enc->stft_tmp_in_buf_time[ch_idx][j] = time_sample_vector; + } + + iusace_complex_fft(scratch_buff, STFT256_HOP_SIZE << 1, ptr_scratch); + + ptr_output[(i * STFT256_HOP_SIZE) << 1] = scratch_buff[0]; + ptr_output[((i * STFT256_HOP_SIZE) << 1) + 1] = scratch_buff[STFT256_HOP_SIZE << 1]; + + for (j = 1; j < STFT256_HOP_SIZE; j++) { + ptr_output[(i * STFT256_HOP_SIZE + j) << 1] = scratch_buff[j << 1]; + ptr_output[((i * STFT256_HOP_SIZE + j) << 1) + 1] = scratch_buff[(j << 1) + 1]; + } + } +} diff --git a/encoder/drc_src/impd_drc_gain_enc.c b/encoder/drc_src/impd_drc_gain_enc.c new file mode 100644 index 0000000..847f7e8 --- /dev/null +++ b/encoder/drc_src/impd_drc_gain_enc.c @@ -0,0 +1,1003 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include +#include +#include "ixheaac_type_def.h" +#include "ixheaace_error_codes.h" + +#include "iusace_cnst.h" +#include "iusace_bitbuffer.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_api.h" +#include "impd_drc_uni_drc_eq.h" +#include "impd_drc_uni_drc_filter_bank.h" +#include "impd_drc_gain_enc.h" +#include "impd_drc_struct_def.h" +#include "impd_drc_tables.h" +#include "impd_drc_enc.h" +#include "impd_drc_mux.h" +#include "iusace_block_switch_const.h" + +#include "iusace_tns_usac.h" +#include "iusace_psy_mod.h" +#include "ixheaace_sbr_header.h" +#include "ixheaace_config.h" +#include "iusace_config.h" + +static FLOAT32 impd_drc_limit_drc_gain(const WORD32 gain_coding_profile, const FLOAT32 gain) { + FLOAT32 limited_drc_gain; + + switch (gain_coding_profile) { + case GAIN_CODING_PROFILE_CONSTANT: + limited_drc_gain = gain; + break; + case GAIN_CODING_PROFILE_CLIPPING: + limited_drc_gain = + MAX(MIN(MAX_DRC_GAIN_CODING_PROFILE2, gain), MIN_DRC_GAIN_CODING_PROFILE2); + break; + case GAIN_CODING_PROFILE_FADING: + limited_drc_gain = + MAX(MIN(MAX_DRC_GAIN_CODING_PROFILE1, gain), MIN_DRC_GAIN_CODING_PROFILE1); + break; + case GAIN_CODING_PROFILE_REGULAR: + limited_drc_gain = + MAX(MIN(MAX_DRC_GAIN_CODING_PROFILE0, gain), MIN_DRC_GAIN_CODING_PROFILE0); + break; + default: + limited_drc_gain = gain; + break; + } + + return limited_drc_gain; +} + +static VOID impd_drc_get_quantized_delta_drc_gain(const WORD32 gain_coding_profile, + const FLOAT32 delta_gain, + FLOAT32 *delta_gain_quant, WORD32 *num_bits, + WORD32 *gain_code) { + LOOPIDX idx; + WORD32 num_entries, opt_index; + WORD32 min_pos_diff_idx = 0; + WORD32 min_neg_diff_idx = 0; + FLOAT32 difference; + FLOAT32 min_pos_diff = 1000.0f; + FLOAT32 min_neg_diff = -1000.0f; + ia_drc_delta_gain_code_entry_struct const *pstr_delta_gain_code_table; + + impd_drc_get_delta_gain_code_table(gain_coding_profile, &pstr_delta_gain_code_table, + &num_entries); + for (idx = 0; idx < num_entries; idx++) { + difference = delta_gain - pstr_delta_gain_code_table[idx].value; + if (difference <= 0.0f) { + if (difference > min_neg_diff) { + min_neg_diff = difference; + min_neg_diff_idx = idx; + } + } else { + if (difference < min_pos_diff) { + min_pos_diff = difference; + min_pos_diff_idx = idx; + } + } + } + if (min_pos_diff >= -min_neg_diff) { + opt_index = min_neg_diff_idx; + } else { + opt_index = min_pos_diff_idx; + } + + *delta_gain_quant = pstr_delta_gain_code_table[opt_index].value; + *num_bits = pstr_delta_gain_code_table[opt_index].size; + *gain_code = pstr_delta_gain_code_table[opt_index].code; +} + +static VOID impd_drc_check_overshoot(const WORD32 t_gain_step, const FLOAT32 gain_0, + const FLOAT32 gain_1, const FLOAT32 slope_0, + const FLOAT32 slope_1, const WORD32 time_delta_min, + WORD32 *overshoot_left, WORD32 *overshoot_right) { + WORD32 t_connect; + FLOAT32 norm_slope_0, norm_slope_1; + FLOAT32 gain_left, gain_right; + FLOAT32 t_gain_step_inv, t_gain_step_inv_2; + FLOAT32 temp_a, temp_b, temp_c, temp_d; + FLOAT32 curve_left, curve_right; + FLOAT32 max_val, min_val; + FLOAT32 tmp, tmp2; + FLOAT32 g_extreme, t_extreme; + FLOAT32 k1, k2; + FLOAT32 slope_norm = 1.0f / (FLOAT32)time_delta_min; + FLOAT32 margin = 0.2f; + FLOAT32 step_inv_2 = 2.0f / t_gain_step; + + *overshoot_left = FALSE; + *overshoot_right = FALSE; + + gain_left = (FLOAT32)pow((FLOAT64)10.0, (FLOAT64)(0.05f * gain_0)); + gain_right = (FLOAT32)pow((FLOAT64)10.0, (FLOAT64)(0.05f * gain_1)); + + norm_slope_0 = slope_0 * slope_norm * SLOPE_FACTOR_DB_TO_LINEAR * gain_left; + norm_slope_1 = slope_1 * slope_norm * SLOPE_FACTOR_DB_TO_LINEAR * gain_right; + + if ((FLOAT32)fabs((FLOAT64)norm_slope_0) < (FLOAT32)fabs((FLOAT64)norm_slope_1)) { + t_connect = (WORD32)(0.5f + 2.0f * (gain_left - gain_right + norm_slope_0 * t_gain_step) / + (norm_slope_0 - norm_slope_1)); + t_connect = t_gain_step - t_connect; + if ((t_connect >= 0) && (t_connect < t_gain_step)) { + return; + } + } else if ((FLOAT32)fabs((FLOAT64)norm_slope_0) > (FLOAT32)fabs((FLOAT64)norm_slope_1)) { + t_connect = (WORD32)(0.5f + 2.0f * (gain_right - gain_left - norm_slope_1 * t_gain_step) / + (norm_slope_0 - norm_slope_1)); + if ((t_connect >= 0) && (t_connect < t_gain_step)) { + return; + } + } + + tmp = 1.5f * step_inv_2 * (gain_right - gain_left) - norm_slope_1 - norm_slope_0; + curve_left = step_inv_2 * (tmp - norm_slope_0); + curve_right = step_inv_2 * (norm_slope_1 - tmp); + + tmp = -norm_slope_0 * t_gain_step - gain_left + gain_right; + if (curve_left >= 0.0f) { + if (tmp + margin < 0.0f) { + *overshoot_left = TRUE; + } + } else { + if (tmp - margin > 0.0f) { + *overshoot_left = TRUE; + } + } + tmp = norm_slope_1 * t_gain_step - gain_right + gain_left; + if (curve_right >= 0.0f) { + if (tmp + margin < 0.0f) { + *overshoot_right = TRUE; + } + } else { + if (tmp - margin > 0.0f) { + *overshoot_right = TRUE; + } + } + + if ((!*overshoot_left) && (!*overshoot_right)) { + t_gain_step_inv = 1.0f / (FLOAT32)t_gain_step; + t_gain_step_inv_2 = t_gain_step_inv * t_gain_step_inv; + k1 = (gain_right - gain_left) * t_gain_step_inv_2; + k2 = norm_slope_1 + norm_slope_0; + + temp_a = t_gain_step_inv * (t_gain_step_inv * k2 - 2.0f * k1); + temp_b = 3.0f * k1 - t_gain_step_inv * (k2 + norm_slope_0); + temp_c = norm_slope_0; + temp_d = gain_left; + tmp = temp_b * temp_b - 3.0f * temp_a * temp_c; + + if (!((tmp < 0.0f) || (temp_a == 0.0f))) { + max_val = MAX(gain_left, gain_right) + margin; + min_val = MIN(gain_left, gain_right) - margin; + tmp = (FLOAT32)sqrt((FLOAT64)tmp); + tmp2 = (1.0f / (3.0f * temp_a)); + + t_extreme = tmp2 * (-temp_b + tmp); + if ((t_extreme > 0.0f) && (t_extreme < t_gain_step)) { + g_extreme = (((temp_a * t_extreme + temp_b) * t_extreme + temp_c) * t_extreme) + temp_d; + if ((g_extreme > max_val) || (g_extreme < min_val)) { + *overshoot_left = TRUE; + } + } + + t_extreme = tmp2 * (-temp_b - tmp); + if ((t_extreme > 0.0f) && (t_extreme < t_gain_step)) { + g_extreme = (((temp_a * t_extreme + temp_b) * t_extreme + temp_c) * t_extreme) + temp_d; + if ((g_extreme > max_val) || (g_extreme < min_val)) { + *overshoot_left = TRUE; + } + } + } + } +} + +static VOID impd_drc_quantize_slope(const FLOAT32 slope, FLOAT32 *slope_quant, + WORD32 *slope_code_index) { + LOOPIDX idx = 0; + const ia_drc_slope_code_table_entry_struct *pstr_slope_code_table = + impd_drc_get_slope_code_table_by_value(); + + while ((idx < 14) && (slope > pstr_slope_code_table[idx].value)) { + idx++; + } + if (idx > 0 && ((pstr_slope_code_table[idx].value - slope) > + (slope - pstr_slope_code_table[idx - 1].value))) { + idx--; + } + + *slope_quant = pstr_slope_code_table[idx].value; + *slope_code_index = pstr_slope_code_table[idx].index; +} + +static VOID impd_drc_get_preliminary_nodes(const ia_drc_gain_enc_struct *pstr_gain_enc, + const FLOAT32 *ptr_drc_gain_per_sample, + FLOAT32 *ptr_drc_gain_per_sample_with_prev_frame, + ia_drc_group_struct *pstr_drc_group, + const WORD32 full_frame, VOID *pstr_scratch) { + LOOPIDX n, k; + WORD32 t, index; + WORD32 drc_frame_size = pstr_gain_enc->drc_frame_size; + WORD32 time_delta_min = pstr_gain_enc->delta_tmin; + WORD32 num_values = drc_frame_size / time_delta_min; + WORD32 offset = time_delta_min / 2; + WORD32 num_gain_values; + WORD32 n_left, n_right; + + FLOAT32 gain, gain_quant, gain_quant_prev; + FLOAT32 quant_error_prev = -1.0f; + FLOAT32 quant_error; + FLOAT32 slope_prev, slope_next; + FLOAT32 f0 = 0.9f; + FLOAT32 f1 = 1.0f - f0; + + WORD32 *ptr_time_at_node = pstr_drc_group->ts_gain; + FLOAT32 *ptr_gain_at_node = pstr_drc_group->drc_gain; + FLOAT32 *ptr_slope_at_node = pstr_drc_group->slope; + FLOAT32 *ptr_gain = ptr_drc_gain_per_sample_with_prev_frame + drc_frame_size; + iusace_scratch_mem *ptr_scratch = (iusace_scratch_mem *)(pstr_scratch); + FLOAT32 *ptr_slope = (FLOAT32 *)ptr_scratch->ptr_drc_scratch_buf; + + memcpy(ptr_drc_gain_per_sample_with_prev_frame, + &(ptr_drc_gain_per_sample_with_prev_frame[drc_frame_size]), + drc_frame_size * sizeof(FLOAT32)); + memcpy(&(ptr_drc_gain_per_sample_with_prev_frame[drc_frame_size]), ptr_drc_gain_per_sample, + drc_frame_size * sizeof(FLOAT32)); + + for (n = 0; n < drc_frame_size; n++) { + ptr_gain[n] *= SCALE_APPROXIMATE_DB; + } + for (n = 0; n < drc_frame_size; n++) { + ptr_gain[n] = f0 * ptr_gain[n - 1] + f1 * ptr_gain[n]; + } + + if (pstr_drc_group->gain_prev_node < 0.f) { + gain_quant_prev = + GAIN_QUANT_STEP_SIZE * + ((WORD32)(-0.5f + GAIN_QUANT_STEP_SIZE_INV * pstr_drc_group->gain_prev_node)); + } else { + gain_quant_prev = + GAIN_QUANT_STEP_SIZE * + ((WORD32)(0.5f + GAIN_QUANT_STEP_SIZE_INV * pstr_drc_group->gain_prev_node)); + } + + k = -1; + for (n = 1; n < num_values + 1; n++) { + gain = ptr_gain[n * time_delta_min - 1]; + if (gain < 0.f) { + gain_quant = GAIN_QUANT_STEP_SIZE * ((WORD32)(-0.5f + GAIN_QUANT_STEP_SIZE_INV * gain)); + } else { + gain_quant = GAIN_QUANT_STEP_SIZE * ((WORD32)(0.5f + GAIN_QUANT_STEP_SIZE_INV * gain)); + } + quant_error = (FLOAT32)fabs((FLOAT64)(gain - gain_quant)); + + slope_prev = (gain - ptr_gain[(n - 1) * time_delta_min - 1]); + if (n == num_values) { + slope_next = 0.2f; + } else { + slope_next = (ptr_gain[(n + 1) * time_delta_min - 1] - gain); + } + + if (gain_quant_prev != gain_quant) { + k++; + quant_error_prev = quant_error; + gain_quant_prev = gain_quant; + ptr_time_at_node[k] = n * time_delta_min - 1; + if ((FLOAT32)fabs((FLOAT64)slope_prev) > 0.1f) { + gain_quant_prev = 1000.0f; + } + } else { + if ((FLOAT32)fabs((FLOAT64)slope_next) > 0.1f) { + if (k < 0) { + k = 0; + } + ptr_time_at_node[k] = n * time_delta_min - 1; + } else { + if (quant_error_prev > quant_error) { + if (k < 0) { + k = 0; + } + quant_error_prev = quant_error; + ptr_time_at_node[k] = n * time_delta_min - 1; + } + } + } + } + if (full_frame == 1) { + if (ptr_time_at_node[k] != drc_frame_size - 1) { + k++; + ptr_time_at_node[k] = drc_frame_size - 1; + } + } + + num_gain_values = k + 1; + if (num_gain_values <= 0) { + if (k < 0) { + k = 0; + } + n = num_values / 2; + index = offset + n * time_delta_min - 1; + ptr_slope[n] = + ptr_drc_gain_per_sample[index + time_delta_min] - ptr_drc_gain_per_sample[index]; + t = (n + 1) * time_delta_min - 1; + ptr_time_at_node[k] = t; + ptr_slope_at_node[k] = ptr_slope[n]; + ptr_gain_at_node[k] = ptr_drc_gain_per_sample[t]; + num_gain_values++; + } + + for (k = 0; k < num_gain_values; k++) { + n_left = MAX(0, ptr_time_at_node[k] - time_delta_min); + n_right = n_left + time_delta_min; + ptr_slope_at_node[k] = ptr_gain[n_right] - ptr_gain[n_left]; + ptr_gain_at_node[k] = ptr_gain[ptr_time_at_node[k]]; + } + + pstr_drc_group->n_gain_values = num_gain_values; +} + +static VOID impd_drc_advance_nodes(ia_drc_gain_enc_struct *pstr_gain_enc, + ia_drc_gain_seq_buf_struct *pstr_drc_gain_seq_buf) { + LOOPIDX idx; + ia_drc_group_struct *pstr_drc_group = &(pstr_drc_gain_seq_buf->str_drc_group); + ia_drc_group_for_output_struct *pstr_drc_group_for_output = + &(pstr_drc_gain_seq_buf->str_drc_group_for_output); + + if (pstr_drc_group_for_output->n_gain_values > 0) { + pstr_drc_group_for_output->time_quant_prev = + pstr_drc_group_for_output->ts_gain_quant[pstr_drc_group_for_output->n_gain_values - 1] - + pstr_gain_enc->drc_frame_size; + pstr_drc_group_for_output->slope_code_index_prev = + pstr_drc_group_for_output->slope_code_index[pstr_drc_group_for_output->n_gain_values - 1]; + pstr_drc_group_for_output->drc_gain_quant_prev = + pstr_drc_group_for_output->drc_gain_quant[pstr_drc_group_for_output->n_gain_values - 1]; + } + for (idx = 0; idx < pstr_drc_group->n_gain_values; idx++) { + pstr_drc_group_for_output->ts_gain_quant[idx] = pstr_drc_group->ts_gain_quant[idx]; + pstr_drc_group_for_output->time_delta_quant[idx] = pstr_drc_group->time_delta_quant[idx]; + pstr_drc_group_for_output->slope_quant[idx] = pstr_drc_group->slope_quant[idx]; + pstr_drc_group_for_output->slope_code_index[idx] = pstr_drc_group->slope_code_index[idx]; + pstr_drc_group_for_output->gain_code[idx] = pstr_drc_group->gain_code[idx]; + pstr_drc_group_for_output->gain_code_length[idx] = pstr_drc_group->gain_code_length[idx]; + pstr_drc_group_for_output->drc_gain_quant[idx] = pstr_drc_group->drc_gain_quant[idx]; + } + pstr_drc_group_for_output->n_gain_values = pstr_drc_group->n_gain_values; +} + +static VOID impd_drc_post_process_nodes( + ia_drc_gain_enc_struct *pstr_gain_enc, + ia_drc_delta_time_code_table_entry_struct *pstr_delta_time_code_table, + ia_drc_gain_seq_buf_struct *pstr_drc_gain_seq_buf, VOID *pstr_scratch) { + LOOPIDX k, n; + WORD32 time_mandatory_node; + WORD32 n_removed, move_on; + WORD32 idx_left, idx_right; + WORD32 idx_0, idx_1, idx_2, idx_3; + WORD32 left, mid, right; + WORD32 overshoot_right, overshoot_left; + WORD32 cod_slope_zero = 0x7; + WORD32 slope_changed = TRUE; + WORD32 repeat_check = TRUE; + WORD32 time_prev = -1; + WORD32 time_delta_min = pstr_gain_enc->delta_tmin; + + FLOAT32 delta_gain; + FLOAT32 delta_gain_quant; + FLOAT32 gain_value_quant; + FLOAT32 slope_average; + FLOAT32 slope_of_nodes_left; + FLOAT32 slope_of_nodes_right; + FLOAT32 thr_low, thr_high; + FLOAT32 delta_left, delta_right; + FLOAT32 slope_0, slope_1, slope_2; + + const ia_drc_slope_code_table_entry_struct *pstr_slope_code_table; + ia_drc_group_for_output_struct *pstr_drc_group_for_output = + &(pstr_drc_gain_seq_buf->str_drc_group_for_output); + WORD32 num_gain_values = pstr_drc_group_for_output->n_gain_values; + FLOAT32 drc_gain_quant_prev = pstr_drc_group_for_output->drc_gain_quant_prev; + + iusace_scratch_mem *ptr_scratch = (iusace_scratch_mem *)(pstr_scratch); + FLOAT32 *ptr_gain_buf = (FLOAT32 *)((UWORD8 *)ptr_scratch->ptr_drc_scratch_buf); + WORD32 *ptr_time_buf = + (WORD32 *)(((UWORD8 *)ptr_gain_buf) + (N_UNIDRC_GAIN_MAX + 2) * sizeof(ptr_gain_buf[0])); + WORD32 *ptr_slope_code_index_buf = + (WORD32 *)(((UWORD8 *)ptr_time_buf) + (N_UNIDRC_GAIN_MAX + 2) * sizeof(ptr_time_buf[0])); + WORD32 *ptr_remove = (WORD32 *)(((UWORD8 *)ptr_slope_code_index_buf) + + (N_UNIDRC_GAIN_MAX + 2) * sizeof(ptr_slope_code_index_buf[0])); + + if (pstr_drc_gain_seq_buf->str_gain_set_params.full_frame != 1) { + time_mandatory_node = 99999999; + } else { + time_mandatory_node = pstr_gain_enc->drc_frame_size - 1; + } + + ptr_time_buf[0] = pstr_drc_group_for_output->time_quant_prev; + ptr_gain_buf[0] = pstr_drc_group_for_output->drc_gain_quant_prev; + for (k = 0; k < num_gain_values; k++) { + ptr_time_buf[k + 1] = pstr_drc_group_for_output->ts_gain_quant[k]; + ptr_gain_buf[k + 1] = pstr_drc_group_for_output->drc_gain_quant[k]; + } + ptr_time_buf[k + 1] = pstr_drc_group_for_output->time_quant_next; + ptr_gain_buf[k + 1] = pstr_drc_group_for_output->drc_gain_quant_next; + + if (num_gain_values > 1) { + idx_left = 0; + idx_right = 2; + n_removed = 0; + for (k = 0; k <= num_gain_values + 1; k++) { + ptr_remove[k] = FALSE; + } + while (idx_right <= num_gain_values + 1) { + if ((ptr_gain_buf[idx_left] == ptr_gain_buf[idx_right - 1]) && + (ptr_gain_buf[idx_right - 1] == ptr_gain_buf[idx_right]) && + (num_gain_values - n_removed > 1) && + (ptr_time_buf[idx_right - 1] != time_mandatory_node)) { + ptr_remove[idx_right - 1] = TRUE; + idx_right++; + n_removed++; + } else { + idx_left = idx_right - 1; + idx_right++; + } + } + + n = 1; + for (k = 1; k <= num_gain_values + 1; k++) { + if (!ptr_remove[k]) { + ptr_time_buf[n] = ptr_time_buf[k]; + ptr_gain_buf[n] = ptr_gain_buf[k]; + n++; + } + } + + n = 0; + for (k = 0; k < num_gain_values; k++) { + if (!ptr_remove[k + 1]) { + pstr_drc_group_for_output->ts_gain_quant[n] = pstr_drc_group_for_output->ts_gain_quant[k]; + pstr_drc_group_for_output->time_delta_quant[n] = + pstr_drc_group_for_output->time_delta_quant[k]; + pstr_drc_group_for_output->slope_quant[n] = pstr_drc_group_for_output->slope_quant[k]; + pstr_drc_group_for_output->slope_code_index[n] = + pstr_drc_group_for_output->slope_code_index[k]; + pstr_drc_group_for_output->gain_code[n] = pstr_drc_group_for_output->gain_code[k]; + pstr_drc_group_for_output->gain_code_length[n] = + pstr_drc_group_for_output->gain_code_length[k]; + pstr_drc_group_for_output->drc_gain_quant[n] = + pstr_drc_group_for_output->drc_gain_quant[k]; + n++; + } + } + num_gain_values = n; + } + + if (num_gain_values > 2) { + move_on = FALSE; + idx_0 = 0; + idx_1 = 1; + idx_2 = 2; + idx_3 = 3; + n_removed = 0; + for (k = 0; k <= num_gain_values + 1; k++) { + ptr_remove[k] = FALSE; + } + while (idx_3 < num_gain_values + 1) { + if (move_on) { + move_on = FALSE; + idx_0 = idx_1; + idx_1 = idx_2; + idx_2 = idx_3; + idx_3++; + } + if (ptr_gain_buf[idx_1] != ptr_gain_buf[idx_2]) { + move_on = TRUE; + } else { + delta_left = ptr_gain_buf[idx_1] - ptr_gain_buf[idx_0]; + delta_right = ptr_gain_buf[idx_3] - ptr_gain_buf[idx_2]; + + if (((FLOAT32)fabs((FLOAT64)delta_left) < 0.26f) || + ((FLOAT32)fabs((FLOAT64)delta_right) < 0.26f)) { + if ((delta_left > 0.0f) && (delta_right > 0.0f) && + (ptr_time_buf[idx_1] != time_mandatory_node)) { + ptr_remove[idx_1] = TRUE; + pstr_drc_group_for_output->gain_code[idx_2 - 1] = + pstr_drc_group_for_output->gain_code[idx_1 - 1]; + pstr_drc_group_for_output->gain_code_length[idx_2 - 1] = + pstr_drc_group_for_output->gain_code_length[idx_1 - 1]; + idx_1 = idx_2; + idx_2 = idx_3; + idx_3++; + n_removed++; + } else if ((delta_left < 0.0f) && (delta_right < 0.0f) && + (ptr_time_buf[idx_2] != time_mandatory_node)) { + ptr_remove[idx_2] = TRUE; + idx_2 = idx_3; + idx_3++; + n_removed++; + } else { + move_on = TRUE; + } + } else { + move_on = TRUE; + } + } + } + + n = 1; + for (k = 1; k <= num_gain_values + 1; k++) { + if (!ptr_remove[k]) { + ptr_gain_buf[n] = ptr_gain_buf[k]; + ptr_time_buf[n] = ptr_time_buf[k]; + n++; + } + } + + n = 0; + for (k = 0; k < num_gain_values; k++) { + if (!ptr_remove[k + 1]) { + pstr_drc_group_for_output->ts_gain_quant[n] = pstr_drc_group_for_output->ts_gain_quant[k]; + pstr_drc_group_for_output->time_delta_quant[n] = + pstr_drc_group_for_output->time_delta_quant[k]; + pstr_drc_group_for_output->slope_quant[n] = pstr_drc_group_for_output->slope_quant[k]; + pstr_drc_group_for_output->slope_code_index[n] = + pstr_drc_group_for_output->slope_code_index[k]; + pstr_drc_group_for_output->gain_code[n] = pstr_drc_group_for_output->gain_code[k]; + pstr_drc_group_for_output->gain_code_length[n] = + pstr_drc_group_for_output->gain_code_length[k]; + pstr_drc_group_for_output->drc_gain_quant[n] = + pstr_drc_group_for_output->drc_gain_quant[k]; + n++; + } + } + num_gain_values = n; + } + + for (k = 1; k <= num_gain_values; k++) { + if ((ptr_gain_buf[k - 1] < ptr_gain_buf[k]) && (ptr_gain_buf[k] > ptr_gain_buf[k + 1])) { + pstr_drc_group_for_output->slope_code_index[k - 1] = cod_slope_zero; + pstr_drc_group_for_output->slope_quant[k - 1] = 0.0f; + } + if ((ptr_gain_buf[k - 1] > ptr_gain_buf[k]) && (ptr_gain_buf[k] < ptr_gain_buf[k + 1])) { + pstr_drc_group_for_output->slope_code_index[k - 1] = cod_slope_zero; + pstr_drc_group_for_output->slope_quant[k - 1] = 0.0f; + } + } + + if (ptr_gain_buf[0] == ptr_gain_buf[1]) { + pstr_drc_group_for_output->slope_code_index[0] = cod_slope_zero; + pstr_drc_group_for_output->slope_quant[0] = 0.0f; + } + for (k = 0; k < num_gain_values - 1; k++) { + if (ptr_gain_buf[k + 1] == ptr_gain_buf[k + 2]) { + pstr_drc_group_for_output->slope_code_index[k] = cod_slope_zero; + pstr_drc_group_for_output->slope_code_index[k + 1] = cod_slope_zero; + pstr_drc_group_for_output->slope_quant[k] = 0.0f; + pstr_drc_group_for_output->slope_quant[k + 1] = 0.0f; + } + } + if (ptr_gain_buf[k + 1] == ptr_gain_buf[k + 2]) { + pstr_drc_group_for_output->slope_code_index[k] = cod_slope_zero; + pstr_drc_group_for_output->slope_quant[k] = 0.0f; + } + + ptr_slope_code_index_buf[0] = pstr_drc_group_for_output->slope_code_index_prev; + for (k = 0; k < num_gain_values; k++) { + ptr_slope_code_index_buf[k + 1] = pstr_drc_group_for_output->slope_code_index[k]; + } + ptr_slope_code_index_buf[k + 1] = pstr_drc_group_for_output->slope_code_index_next; + + for (k = 0; k <= num_gain_values + 1; k++) { + ptr_remove[k] = FALSE; + } + + if (num_gain_values > 1) { + left = 0; + mid = 1; + right = 2; + n_removed = 0; + while ((right <= num_gain_values + 1) && (num_gain_values - n_removed > 1)) { + if (((ptr_time_buf[mid] - ptr_time_buf[left]) > 0) && + (FLOAT32)fabs((FLOAT64)(ptr_gain_buf[left] - ptr_gain_buf[right])) < + MAX_DRC_GAIN_DELTA_BEFORE_QUANT) { + slope_of_nodes_left = + (ptr_gain_buf[mid] - ptr_gain_buf[left]) / (ptr_time_buf[mid] - ptr_time_buf[left]); + slope_of_nodes_right = + (ptr_gain_buf[right] - ptr_gain_buf[mid]) / (ptr_time_buf[right] - ptr_time_buf[mid]); + + if (slope_of_nodes_left >= 0.0f) { + if ((slope_of_nodes_left < slope_of_nodes_right * SLOPE_CHANGE_THR) && + (slope_of_nodes_left * SLOPE_CHANGE_THR > slope_of_nodes_right)) { + slope_average = 0.5f * time_delta_min * (slope_of_nodes_left + slope_of_nodes_right); + thr_low = slope_average / SLOPE_QUANT_THR; + thr_high = slope_average * SLOPE_QUANT_THR; + slope_0 = impd_drc_decode_slope_idx_value(ptr_slope_code_index_buf[left]); + slope_1 = impd_drc_decode_slope_idx_value(ptr_slope_code_index_buf[mid]); + slope_2 = impd_drc_decode_slope_idx_value(ptr_slope_code_index_buf[right]); + + if (((slope_0 < thr_high) && (slope_0 > thr_low)) && + ((slope_1 < thr_high) && (slope_1 > thr_low)) && + ((slope_2 < thr_high) && (slope_2 > thr_low)) && + (ptr_time_buf[mid] != time_mandatory_node)) { + ptr_remove[mid] = TRUE; + n_removed++; + mid = right; + right++; + } else { + left = mid; + mid = right; + right++; + } + } else { + left = mid; + mid = right; + right++; + } + } else { + if ((-slope_of_nodes_left < -slope_of_nodes_right * SLOPE_CHANGE_THR) && + (-slope_of_nodes_left * SLOPE_CHANGE_THR > -slope_of_nodes_right)) { + slope_average = -0.5f * time_delta_min * (slope_of_nodes_left + slope_of_nodes_right); + thr_low = slope_average / SLOPE_QUANT_THR; + thr_high = slope_average * SLOPE_QUANT_THR; + slope_0 = -impd_drc_decode_slope_idx_value(ptr_slope_code_index_buf[left]); + slope_1 = -impd_drc_decode_slope_idx_value(ptr_slope_code_index_buf[mid]); + slope_2 = -impd_drc_decode_slope_idx_value(ptr_slope_code_index_buf[right]); + + if (((slope_0 < thr_high) && (slope_0 > thr_low)) && + ((slope_1 < thr_high) && (slope_1 > thr_low)) && + ((slope_2 < thr_high) && (slope_2 > thr_low)) && + (ptr_time_buf[mid] != time_mandatory_node)) { + ptr_remove[mid] = TRUE; + n_removed++; + mid = right; + right++; + } else { + left = mid; + mid = right; + right++; + } + } else { + left = mid; + mid = right; + right++; + } + } + } else { + left = mid; + mid = right; + right++; + } + } + + n = 1; + for (k = 1; k <= num_gain_values + 1; k++) { + if (!ptr_remove[k]) { + ptr_time_buf[n] = ptr_time_buf[k]; + ptr_gain_buf[n] = ptr_gain_buf[k]; + ptr_slope_code_index_buf[n] = ptr_slope_code_index_buf[k]; + n++; + } + } + + n = 0; + for (k = 0; k < num_gain_values; k++) { + if (!ptr_remove[k + 1]) { + pstr_drc_group_for_output->ts_gain_quant[n] = pstr_drc_group_for_output->ts_gain_quant[k]; + pstr_drc_group_for_output->time_delta_quant[n] = + pstr_drc_group_for_output->time_delta_quant[k]; + pstr_drc_group_for_output->gain_code[n] = pstr_drc_group_for_output->gain_code[k]; + pstr_drc_group_for_output->gain_code_length[n] = + pstr_drc_group_for_output->gain_code_length[k]; + pstr_drc_group_for_output->slope_quant[n] = pstr_drc_group_for_output->slope_quant[k]; + pstr_drc_group_for_output->slope_code_index[n] = + pstr_drc_group_for_output->slope_code_index[k]; + pstr_drc_group_for_output->drc_gain_quant[n] = + pstr_drc_group_for_output->drc_gain_quant[k]; + n++; + } + } + num_gain_values = n; + } + pstr_drc_group_for_output->n_gain_values = num_gain_values; + + k = 0; + while (repeat_check) { + repeat_check = FALSE; + + while (k < num_gain_values) { + if (slope_changed) { + slope_changed = FALSE; + } else { + k++; + } + if ((ptr_slope_code_index_buf[k] != cod_slope_zero) || + (ptr_slope_code_index_buf[k + 1] != cod_slope_zero)) { + impd_drc_check_overshoot(ptr_time_buf[k + 1] - ptr_time_buf[k], ptr_gain_buf[k], + ptr_gain_buf[k + 1], + impd_drc_decode_slope_idx_value(ptr_slope_code_index_buf[k]), + impd_drc_decode_slope_idx_value(ptr_slope_code_index_buf[k + 1]), + time_delta_min, &overshoot_left, &overshoot_right); + + if (overshoot_right || overshoot_left) { + if ((k == 0) || + (impd_drc_decode_slope_idx_magnitude(ptr_slope_code_index_buf[k]) < + impd_drc_decode_slope_idx_magnitude(ptr_slope_code_index_buf[k + 1]))) { + if (ptr_slope_code_index_buf[k + 1] < cod_slope_zero) { + ptr_slope_code_index_buf[k + 1] = ptr_slope_code_index_buf[k + 1] + 1; + slope_changed = TRUE; + } else if (ptr_slope_code_index_buf[k + 1] > cod_slope_zero) { + ptr_slope_code_index_buf[k + 1] = ptr_slope_code_index_buf[k + 1] - 1; + slope_changed = TRUE; + } + } else if ((k == num_gain_values) || + (impd_drc_decode_slope_idx_magnitude(ptr_slope_code_index_buf[k]) > + impd_drc_decode_slope_idx_magnitude(ptr_slope_code_index_buf[k + 1]))) { + if (ptr_slope_code_index_buf[k] < cod_slope_zero) { + ptr_slope_code_index_buf[k] = ptr_slope_code_index_buf[k] + 1; + slope_changed = TRUE; + repeat_check = TRUE; + } else if (ptr_slope_code_index_buf[k] > cod_slope_zero) { + ptr_slope_code_index_buf[k] = ptr_slope_code_index_buf[k] - 1; + slope_changed = TRUE; + repeat_check = TRUE; + } + } + } + } + } + } + for (k = 0; k < num_gain_values; k++) { + pstr_drc_group_for_output->slope_code_index[k] = ptr_slope_code_index_buf[k + 1]; + pstr_drc_group_for_output->slope_quant[k] = + impd_drc_decode_slope_idx_value(ptr_slope_code_index_buf[k + 1]); + } + + for (n = 0; n < num_gain_values; n++) { + pstr_drc_group_for_output->time_delta_code_index[n] = + MAX((pstr_drc_group_for_output->ts_gain_quant[n] - time_prev) / time_delta_min, 1); + + time_prev += (pstr_drc_group_for_output->time_delta_code_index[n]) * time_delta_min; + + if (n != 0) { + delta_gain = pstr_drc_group_for_output->drc_gain_quant[n] - drc_gain_quant_prev; + impd_drc_get_quantized_delta_drc_gain( + pstr_drc_gain_seq_buf->str_gain_set_params.gain_coding_profile, delta_gain, + &delta_gain_quant, &(pstr_drc_group_for_output->gain_code_length[n]), + &(pstr_drc_group_for_output->gain_code[n])); + gain_value_quant = delta_gain_quant + drc_gain_quant_prev; + } else { + impd_drc_enc_initial_gain(pstr_drc_gain_seq_buf->str_gain_set_params.gain_coding_profile, + pstr_drc_group_for_output->drc_gain_quant[n], &gain_value_quant, + &(pstr_drc_group_for_output->gain_code_length[n]), + &(pstr_drc_group_for_output->gain_code[n])); + } + drc_gain_quant_prev = gain_value_quant; + pstr_drc_group_for_output->drc_gain_quant[n] = gain_value_quant; + } + + pstr_drc_group_for_output->coding_mode = 1; + if (num_gain_values == 1) { + if (pstr_drc_gain_seq_buf->str_gain_set_params.gain_interpolation_type != + GAIN_INTERPOLATION_TYPE_SPLINE) { + if (pstr_drc_group_for_output->time_delta_code_index[0] > + (pstr_gain_enc->drc_frame_size / pstr_gain_enc->delta_tmin)) { + pstr_drc_group_for_output->coding_mode = 0; + } + } else { + if (impd_drc_decode_slope_idx_magnitude(ptr_slope_code_index_buf[1]) == 0.0f) { + if ((pstr_drc_group_for_output->time_delta_code_index[0] == 0) || + (pstr_drc_group_for_output->time_delta_code_index[0] > 28)) { + pstr_drc_group_for_output->coding_mode = 0; + } + if ((impd_drc_decode_slope_idx_magnitude(ptr_slope_code_index_buf[0]) == 0.0f) && + (impd_drc_decode_slope_idx_magnitude(ptr_slope_code_index_buf[2]) == 0.0f) && + ((FLOAT32)fabs((FLOAT64)(ptr_gain_buf[1] - ptr_gain_buf[0])) < 0.126f) && + ((FLOAT32)fabs((FLOAT64)(ptr_gain_buf[2] - ptr_gain_buf[1])) < 0.126f)) { + pstr_drc_group_for_output->coding_mode = 0; + } + } + } + } + + if (pstr_drc_group_for_output->coding_mode == 1) { + pstr_slope_code_table = impd_drc_get_slope_code_table_by_value(); + for (n = 0; n < num_gain_values; n++) { + pstr_drc_group_for_output->slope_code_size[n] = + pstr_slope_code_table[ptr_slope_code_index_buf[n + 1]].size; + pstr_drc_group_for_output->slope_code[n] = + pstr_slope_code_table[ptr_slope_code_index_buf[n + 1]].code; + } + + for (n = 0; n < num_gain_values; n++) { + pstr_drc_group_for_output->time_delta_code_size[n] = + pstr_delta_time_code_table[pstr_drc_group_for_output->time_delta_code_index[n]].size; + pstr_drc_group_for_output->time_delta_code[n] = + pstr_delta_time_code_table[pstr_drc_group_for_output->time_delta_code_index[n]].code; + } + } +} + +static VOID impd_drc_quantize_drc_frame( + const WORD32 drc_frame_size, const WORD32 time_delta_min, const WORD32 num_gain_values_max, + const FLOAT32 *ptr_drc_gain_per_sample_with_prev_frame, + const WORD32 *ptr_delta_time_quant_table, const WORD32 gain_coding_profile, + ia_drc_group_struct *pstr_drc_group, + ia_drc_group_for_output_struct *pstr_drc_group_for_output) { + LOOPIDX i, n; + WORD32 t, k = 0; + WORD32 num_bits, code, tmp; + WORD32 t_left, t_right; + WORD32 time_delta_left, time_delta_right; + WORD32 restart = TRUE; + WORD32 num_drc_gain_values = pstr_drc_group->n_gain_values; + + FLOAT32 slope; + FLOAT32 delta_gain; + FLOAT32 gain_value_quant; + FLOAT32 delta_gain_quant; + FLOAT32 max_time_deviation; + FLOAT32 drc_gain_per_sample_limited; + + WORD32 *ptr_time_at_node = pstr_drc_group->ts_gain; + WORD32 *ptr_ts_gain_quant = pstr_drc_group->ts_gain_quant; + WORD32 *ptr_slope_code_index = pstr_drc_group->slope_code_index; + FLOAT32 *drc_gain_quant_prev = &(pstr_drc_group->drc_gain_quant_prev); + FLOAT32 *ptr_gain_at_node = pstr_drc_group->drc_gain; + FLOAT32 *ptr_slope_at_node = pstr_drc_group->slope; + FLOAT32 *ptr_slope_quant = pstr_drc_group->slope_quant; + const FLOAT32 *ptr_drc_gain_per_sample = + ptr_drc_gain_per_sample_with_prev_frame + drc_frame_size; + + while (restart) { + n = 0; + restart = FALSE; + while ((n < num_drc_gain_values) && (restart == FALSE)) { + if (n == 0) { + time_delta_left = ptr_time_at_node[n]; + time_delta_right = ptr_time_at_node[n + 1] - ptr_time_at_node[n]; + } else if (n < num_drc_gain_values - 1) { + time_delta_left = ptr_time_at_node[n] - ptr_time_at_node[n - 1]; + time_delta_right = ptr_time_at_node[n + 1] - ptr_time_at_node[n]; + } else { + time_delta_left = ptr_time_at_node[n] - ptr_time_at_node[n - 1]; + time_delta_right = drc_frame_size - ptr_time_at_node[n]; + } + max_time_deviation = MAX_TIME_DEVIATION_FACTOR * MIN(time_delta_left, time_delta_right); + max_time_deviation = MAX(time_delta_min, max_time_deviation); + + i = 0; + while ((i < num_gain_values_max - 2) && (ptr_delta_time_quant_table[i] < time_delta_left)) { + i++; + } + if (i > 0) { + if (ptr_delta_time_quant_table[i] - time_delta_left > + time_delta_left - ptr_delta_time_quant_table[i - 1]) { + i--; + } + if (ptr_delta_time_quant_table[i] >= drc_frame_size) { + i--; + } + } + if (abs(ptr_delta_time_quant_table[i] - time_delta_left) > max_time_deviation) { + if (ptr_delta_time_quant_table[i] > time_delta_left) { + i--; + } + for (k = num_drc_gain_values; k > n; k--) { + ptr_time_at_node[k] = ptr_time_at_node[k - 1]; + ptr_slope_at_node[k] = ptr_slope_at_node[k - 1]; + ptr_gain_at_node[k] = ptr_gain_at_node[k - 1]; + } + if (n <= 0) { + ptr_time_at_node[n] = ptr_delta_time_quant_table[i]; + } else { + ptr_time_at_node[n] = ptr_time_at_node[n - 1] + ptr_delta_time_quant_table[i]; + } + + t = ptr_time_at_node[n]; + ptr_gain_at_node[n] = ptr_drc_gain_per_sample[t]; + t_left = MAX(0, t - time_delta_min / 2); + t_right = MIN(drc_frame_size, t_left + time_delta_min / 2); + ptr_slope_at_node[n] = ptr_drc_gain_per_sample[t_right] - ptr_drc_gain_per_sample[t_left]; + num_drc_gain_values++; + restart = TRUE; + } + n++; + } + } + + ptr_ts_gain_quant[0] = + (WORD32)(time_delta_min * (ptr_time_at_node[0] + 0.5f) / (FLOAT32)time_delta_min); + k = 1; + for (n = 1; n < num_drc_gain_values; n++) { + tmp = (WORD32)(time_delta_min * (ptr_time_at_node[n] + 0.5f) / (FLOAT32)time_delta_min); + if (tmp > ptr_ts_gain_quant[k - 1]) { + ptr_ts_gain_quant[k] = tmp; + k++; + } + } + + num_drc_gain_values = k; + pstr_drc_group->n_gain_values = num_drc_gain_values; + for (n = 0; n < num_drc_gain_values; n++) { + ptr_gain_at_node[n] = ptr_drc_gain_per_sample[ptr_ts_gain_quant[n]]; + drc_gain_per_sample_limited = + impd_drc_limit_drc_gain(gain_coding_profile, ptr_gain_at_node[n]); + + if (n != 0) { + delta_gain = drc_gain_per_sample_limited - *drc_gain_quant_prev; + impd_drc_get_quantized_delta_drc_gain(gain_coding_profile, delta_gain, &delta_gain_quant, + &num_bits, &code); + gain_value_quant = delta_gain_quant + *drc_gain_quant_prev; + } else { + impd_drc_enc_initial_gain(gain_coding_profile, drc_gain_per_sample_limited, + &gain_value_quant, &num_bits, &code); + } + pstr_drc_group->gain_code[n] = code; + pstr_drc_group->gain_code_length[n] = num_bits; + pstr_drc_group->drc_gain_quant[n] = gain_value_quant; + *drc_gain_quant_prev = gain_value_quant; + + t_right = MIN(drc_frame_size - 1, ptr_ts_gain_quant[n] + time_delta_min / 2); + t_left = t_right - time_delta_min; + slope = ptr_drc_gain_per_sample[t_right] - ptr_drc_gain_per_sample[t_left]; + ptr_slope_at_node[n] = slope; + impd_drc_quantize_slope(slope, &(ptr_slope_quant[n]), &(ptr_slope_code_index[n])); + } + + pstr_drc_group->n_gain_values = num_drc_gain_values; + pstr_drc_group->gain_prev_node = ptr_gain_at_node[num_drc_gain_values - 1]; + pstr_drc_group_for_output->time_quant_next = pstr_drc_group->ts_gain_quant[0] + drc_frame_size; + pstr_drc_group_for_output->slope_code_index_next = pstr_drc_group->slope_code_index[0]; + pstr_drc_group_for_output->drc_gain_quant_next = pstr_drc_group->drc_gain_quant[0]; +} + +VOID impd_drc_quantize_and_encode_drc_gain( + ia_drc_gain_enc_struct *pstr_gain_enc, const FLOAT32 *ptr_drc_gain_per_sample, + FLOAT32 *ptr_drc_gain_per_sample_with_prev_frame, + ia_drc_delta_time_code_table_entry_struct *pstr_delta_time_code_table, + ia_drc_gain_seq_buf_struct *pstr_drc_gain_seq_buf, VOID *pstr_scratch) { + WORD32 drc_frame_size = pstr_gain_enc->drc_frame_size; + const WORD32 *ptr_delta_time_quant_table = pstr_gain_enc->delta_time_quant_table; + ia_drc_group_struct *pstr_drc_group; + ia_drc_group_for_output_struct *pstr_drc_group_for_output; + + impd_drc_advance_nodes(pstr_gain_enc, pstr_drc_gain_seq_buf); + + pstr_drc_group = &(pstr_drc_gain_seq_buf->str_drc_group); + pstr_drc_group_for_output = &(pstr_drc_gain_seq_buf->str_drc_group_for_output); + + impd_drc_get_preliminary_nodes( + pstr_gain_enc, ptr_drc_gain_per_sample, ptr_drc_gain_per_sample_with_prev_frame, + pstr_drc_group, pstr_drc_gain_seq_buf->str_gain_set_params.full_frame, pstr_scratch); + + impd_drc_quantize_drc_frame(drc_frame_size, pstr_gain_enc->delta_tmin, + pstr_gain_enc->drc_frame_size / pstr_gain_enc->delta_tmin, + ptr_drc_gain_per_sample_with_prev_frame, ptr_delta_time_quant_table, + pstr_drc_gain_seq_buf->str_gain_set_params.gain_coding_profile, + pstr_drc_group, pstr_drc_group_for_output); + + impd_drc_post_process_nodes(pstr_gain_enc, pstr_delta_time_code_table, pstr_drc_gain_seq_buf, + pstr_scratch); +} diff --git a/encoder/drc_src/impd_drc_gain_enc.h b/encoder/drc_src/impd_drc_gain_enc.h new file mode 100644 index 0000000..026b8c8 --- /dev/null +++ b/encoder/drc_src/impd_drc_gain_enc.h @@ -0,0 +1,211 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +#include "impd_drc_tables.h" + +#define N_UNIDRC_GAIN_MAX (MAX_NODE_COUNT) + +#ifndef M_LOG2_10 +#define M_LOG2_10 (3.32192809488736234787) /* log_2 10 */ +#endif + +#ifndef M_LOG10_E +#define M_LOG10_E (0.4342944819) /* log_10 e */ +#endif + +#define M_LN10_DIV_20 (0.115129254649702284201) /* (log_e 10 / 20) */ + +#define EXP10(x) (exp2(M_LOG2_10 * x)) + +#define MAX_NUM_CHANNELS (32) +#define STFT256_HOP_SIZE (256) +#define IMPD_DRCSPECTRAL_FLOOR (0.02818383f) + +#define IMPD_DRCMAX_NSEQ (40) +#define IMPD_DRCMAX_FRAMESIZE (4096) +#define IMPD_DRCCOMPAND_MAX_NB_POINTS (MAX_NUM_CHANNELS << 3) +#define IMPD_DRCCOMPAND_MAX_NUM_SEGMENTS ((IMPD_DRCCOMPAND_MAX_NB_POINTS + 4) << 1) + +#define MAX_TIME_DEVIATION_FACTOR (0.25f) +#define SLOPE_CHANGE_THR (3.0f) +#define SLOPE_QUANT_THR (8.0f) + +#define GAIN_QUANT_STEP_SIZE (0.125f) +#define GAIN_QUANT_STEP_SIZE_INV (8.0f) + +#define MAX_DRC_GAIN_DELTA_BEFORE_QUANT (1.0f + 0.5f * GAIN_QUANT_STEP_SIZE) + +#define SCALE_APPROXIMATE_DB \ + (0.99657842f) /* factor for converting dB to approximate dB: log2(10)*6/20 */ + +typedef struct ia_drc_compand_chan_param_struct { + FLOAT64 attack; + FLOAT64 decay; + FLOAT64 volume; +} ia_drc_compand_chan_param_struct; + +typedef struct ia_drc_compand_segment_struct { + FLOAT64 x, y; + FLOAT64 a, b; +} ia_drc_compand_segment_struct; + +typedef struct ia_drc_compand_struct { + UWORD8 is_valid; + UWORD32 ch_idx; + UWORD32 nb_points; + UWORD32 nb_segments; + ia_drc_compand_segment_struct str_segment[IMPD_DRCCOMPAND_MAX_NUM_SEGMENTS]; + ia_drc_compand_chan_param_struct str_channel_param; + FLOAT64 in_min_lin; + FLOAT64 out_min_lin; + FLOAT64 width_db; + FLOAT64 gain_db; + FLOAT64 initial_volume; +} ia_drc_compand_struct; + +typedef struct ia_drc_stft_gain_calc_struct { + UWORD8 is_valid; + UWORD32 ch_idx; + FLOAT32 theshold; + FLOAT32 ratio; + FLOAT32 attack_ms; + FLOAT32 release_ms; + FLOAT32 alpha_a; + FLOAT32 alpha_r; + FLOAT32 yl_z1[STFT256_HOP_SIZE + 1]; + + UWORD32 nb_points; + UWORD32 nb_segments; + ia_drc_compand_segment_struct str_segment[IMPD_DRCCOMPAND_MAX_NUM_SEGMENTS]; + ia_drc_compand_chan_param_struct str_channel_param; + FLOAT32 in_min_db; + FLOAT32 out_min_db; + FLOAT32 width_db; + FLOAT32 gain_db; + FLOAT32 initial_volume; +} ia_drc_stft_gain_calc_struct; + +typedef struct { + WORD32 n_gain_values; + + FLOAT32 drc_gain_quant[IMPD_DRCMAX_FRAMESIZE]; + WORD32 gain_code[IMPD_DRCMAX_FRAMESIZE]; + WORD32 gain_code_length[IMPD_DRCMAX_FRAMESIZE]; + FLOAT32 slope_quant[IMPD_DRCMAX_FRAMESIZE]; + WORD32 slope_code_index[IMPD_DRCMAX_FRAMESIZE]; + WORD32 ts_gain_quant[IMPD_DRCMAX_FRAMESIZE]; + WORD32 time_delta_quant[IMPD_DRCMAX_FRAMESIZE]; + + FLOAT32 drc_gain[IMPD_DRCMAX_FRAMESIZE]; + FLOAT32 slope[IMPD_DRCMAX_FRAMESIZE]; + WORD32 ts_gain[IMPD_DRCMAX_FRAMESIZE]; + + FLOAT32 gain_prev_node; + FLOAT32 drc_gain_quant_prev; + +} ia_drc_group_struct; + +typedef struct { + WORD32 n_gain_values; + + FLOAT32 drc_gain_quant[IMPD_DRCMAX_FRAMESIZE]; + WORD32 gain_code[IMPD_DRCMAX_FRAMESIZE]; + WORD32 gain_code_length[IMPD_DRCMAX_FRAMESIZE]; + FLOAT32 slope_quant[IMPD_DRCMAX_FRAMESIZE]; + WORD32 slope_code_index[IMPD_DRCMAX_FRAMESIZE]; + WORD32 ts_gain_quant[IMPD_DRCMAX_FRAMESIZE]; + WORD32 time_delta_quant[IMPD_DRCMAX_FRAMESIZE]; + + WORD32 time_delta_code[IMPD_DRCMAX_FRAMESIZE]; + WORD32 time_delta_code_index[IMPD_DRCMAX_FRAMESIZE]; + WORD32 time_delta_code_size[IMPD_DRCMAX_FRAMESIZE]; + WORD32 slope_code[IMPD_DRCMAX_FRAMESIZE]; + WORD32 slope_code_size[IMPD_DRCMAX_FRAMESIZE]; + + FLOAT32 drc_gain_quant_prev; + FLOAT32 drc_gain_quant_next; + WORD32 time_quant_next; + WORD32 time_quant_prev; + WORD32 slope_code_index_next; + WORD32 slope_code_index_prev; + + WORD32 coding_mode; +} ia_drc_group_for_output_struct; + +typedef struct { + ia_drc_gain_set_params_struct str_gain_set_params; + ia_drc_group_struct str_drc_group; + ia_drc_group_for_output_struct str_drc_group_for_output; +} ia_drc_gain_seq_buf_struct; + +typedef struct { + WORD32 n_sequences; + WORD32 delta_tmin; + WORD32 delta_tmin_default; + WORD32 drc_frame_size; + WORD32 sample_rate; + WORD32 delay_mode; + WORD32 domain; + WORD32 base_ch_count; + ia_drc_uni_drc_config_struct str_uni_drc_config; + ia_drc_loudness_info_set_struct str_loudness_info_set; + FLOAT32 drc_gain_per_sample_with_prev_frame[IMPD_DRCMAX_NSEQ][3 * IMPD_DRCMAX_FRAMESIZE]; + ia_drc_gain_seq_buf_struct str_drc_gain_seq_buf[IMPD_DRCMAX_NSEQ]; + ia_drc_delta_time_code_table_entry_struct + str_delta_time_code_table[2 * IMPD_DRCMAX_FRAMESIZE + 1]; + WORD32 delta_time_quant_table[IMPD_DRCMAX_FRAMESIZE]; + + ia_drc_eq_set_struct str_eq_set; + ia_drc_filter_banks_struct str_filter_banks; + ia_drc_compand_struct str_drc_compand[MAX_DRC_COEFF_COUNT][GAIN_SET_COUNT_MAX]; + ia_drc_stft_gain_calc_struct str_drc_stft_gain_handle[MAX_DRC_COEFF_COUNT][GAIN_SET_COUNT_MAX] + [MAX_BAND_COUNT]; + FLOAT32 stft_tmp_in_buf_time[MAX_NUM_CHANNELS][STFT256_HOP_SIZE]; + FLOAT32 complex_fft_ptr[MAX_NUM_CHANNELS][IMPD_DRCMAX_FRAMESIZE << 1]; +} ia_drc_gain_enc_struct; + +VOID impd_drc_quantize_and_encode_drc_gain( + ia_drc_gain_enc_struct *pstr_gain_enc, const FLOAT32 *ptr_drc_gain_per_sample, + FLOAT32 *ptr_drc_gain_per_sample_with_prev_frame, + ia_drc_delta_time_code_table_entry_struct *pstr_delta_time_code_table, + ia_drc_gain_seq_buf_struct *pstr_drc_gain_seq_buf, VOID *pstr_scratch); + +IA_ERRORCODE impd_drc_td_drc_gain_calc_init(ia_drc_gain_enc_struct *pstr_drc_gain_enc, + WORD32 drc_coefficients_uni_drc_idx, + WORD32 gain_set_idx); + +IA_ERRORCODE impd_drc_stft_drc_gain_calc_init(ia_drc_gain_enc_struct *pstr_drc_gain_enc, + WORD32 drc_coefficients_uni_drc_idx, + WORD32 gain_set_idx, WORD32 band_idx); + +VOID impd_drc_td_drc_gain_calc_process(ia_drc_gain_enc_struct *pstr_drc_gain_enc, + WORD32 drc_coefficients_uni_drc_idx, WORD32 gain_set_idx, + WORD32 num_samples, FLOAT32 *in_buff, FLOAT32 *out_buff); + +VOID impd_drc_stft_drc_gain_calc_process(ia_drc_gain_enc_struct *pstr_drc_gain_enc, + WORD32 drc_coefficients_uni_drc_idx, WORD32 gain_set_idx, + WORD32 band_idx, WORD32 start_sub_band_index, + WORD32 stop_sub_band_index, UWORD32 num_frames, + FLOAT32 *in_buff, FLOAT32 *gain_values); + +VOID impd_drc_stft_drc_convert_to_fd(ia_drc_gain_enc_struct *pstr_drc_gain_enc, + FLOAT32 *ptr_input, UWORD32 ch_idx, UWORD32 frame_size, + FLOAT32 *ptr_output, VOID *pstr_scratch); diff --git a/encoder/drc_src/impd_drc_mux.c b/encoder/drc_src/impd_drc_mux.c new file mode 100644 index 0000000..bb79091 --- /dev/null +++ b/encoder/drc_src/impd_drc_mux.c @@ -0,0 +1,3200 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include +#include "ixheaac_type_def.h" +#include "ixheaac_error_standards.h" +#include "ixheaace_error_codes.h" + +#include "iusace_bitbuffer.h" +#include "iusace_cnst.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" +#include "impd_drc_uni_drc_eq.h" +#include "impd_drc_uni_drc_filter_bank.h" +#include "impd_drc_gain_enc.h" +#include "impd_drc_struct_def.h" +#include "impd_drc_enc.h" +#include "impd_drc_mux.h" + +static IA_ERRORCODE impd_drc_get_drc_complexity_level( + ia_drc_uni_drc_config_struct *pstr_uni_drc_config, ia_drc_gain_enc_struct *pstr_drc_gain_enc, + ia_drc_instructions_uni_drc *pstr_drc_instructions_uni_drc, VOID *ptr_scratch) { + IA_ERRORCODE err_code = IA_NO_ERROR; + LOOPIDX c, g, k, i, group; + WORD32 band_count; + WORD32 gain_set_index; + WORD32 skip_set; + WORD32 gain_set_index_offset; + WORD32 parametric_drc_type = 0; + WORD32 channel_count_side_chain; + WORD32 channel_count_drom_downmix_id; + WORD32 channel_count_temp; + WORD32 weighting_filter_order; + WORD32 channel_count = pstr_uni_drc_config->str_channel_layout.base_ch_count; + FLOAT32 w_mod, cplx, cplx_tmp, ratio; + ia_drc_gain_modifiers_struct *pstr_gain_modifiers = NULL; + ia_drc_shape_filter_block_params_struct *pstr_shape_filter_block_params = NULL; + ia_drc_gain_set_params_struct *pstr_gain_set_params = NULL; + ia_drc_parametric_drc_instructions_struct *pstr_parametric_drc_instructions = NULL; + ia_drc_parametric_drc_gain_set_params_struct *pstr_parametric_drc_gain_set_params = NULL; + + if (pstr_drc_instructions_uni_drc->drc_apply_to_downmix != 0 && + ((pstr_drc_instructions_uni_drc->downmix_id == 0x7F) || + (pstr_drc_instructions_uni_drc->additional_downmix_id_count != 0))) { + channel_count = 1; + } else if ((pstr_drc_instructions_uni_drc->drc_apply_to_downmix != 0) && + (pstr_drc_instructions_uni_drc->downmix_id != 0) && + (pstr_drc_instructions_uni_drc->downmix_id != 0x7F) && + (pstr_drc_instructions_uni_drc->additional_downmix_id_count == 0)) { + for (i = 0; i < pstr_uni_drc_config->downmix_instructions_count; i++) { + if (pstr_drc_instructions_uni_drc->downmix_id == + pstr_uni_drc_config->str_downmix_instructions[i].downmix_id) { + break; + } + } + if (i == pstr_uni_drc_config->downmix_instructions_count) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG; + } + channel_count = pstr_uni_drc_config->str_downmix_instructions[i].target_ch_count; + } + + pstr_drc_instructions_uni_drc->drc_channel_count = channel_count; + group = 0; + for (c = 0; c < pstr_drc_instructions_uni_drc->drc_channel_count; c++) { + gain_set_index = pstr_drc_instructions_uni_drc->gain_set_index[c]; + skip_set = FALSE; + if (gain_set_index < 0) { + pstr_drc_instructions_uni_drc->channel_group_for_channel[c] = -1; + } else { + for (k = c - 1; k >= 0; k--) { + if (pstr_drc_instructions_uni_drc->gain_set_index[k] == gain_set_index) { + pstr_drc_instructions_uni_drc->channel_group_for_channel[c] = + pstr_drc_instructions_uni_drc->channel_group_for_channel[k]; + skip_set = TRUE; + } + } + if (skip_set == FALSE) { + pstr_drc_instructions_uni_drc->channel_group_for_channel[c] = group; + group++; + } + } + } + if (group != pstr_drc_instructions_uni_drc->num_drc_channel_groups) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG; + } + + for (g = 0; g < pstr_drc_instructions_uni_drc->num_drc_channel_groups; g++) { + pstr_drc_instructions_uni_drc->num_channels_per_channel_group[g] = 0; + for (c = 0; c < pstr_drc_instructions_uni_drc->drc_channel_count; c++) { + if (pstr_drc_instructions_uni_drc->channel_group_for_channel[c] == g) { + pstr_drc_instructions_uni_drc->num_channels_per_channel_group[g]++; + } + } + } + + cplx = 0.0f; + + if (pstr_drc_gain_enc->domain == TIME_DOMAIN) { + w_mod = COMPLEXITY_W_MOD_TIME; + } else { + w_mod = COMPLEXITY_W_MOD_SUBBAND; + } + for (c = 0; c < pstr_drc_instructions_uni_drc->drc_channel_count; c++) { + if (pstr_drc_instructions_uni_drc->gain_set_index[c] >= 0) { + cplx += w_mod; + } + } + + if (pstr_drc_gain_enc->domain != TIME_DOMAIN) { + pstr_gain_set_params = + pstr_uni_drc_config->str_uni_drc_config_ext.str_drc_coefficients_uni_drc_v1[0] + .str_gain_set_params; + for (c = 0; c < pstr_drc_instructions_uni_drc->drc_channel_count; c++) { + gain_set_index = pstr_drc_instructions_uni_drc->gain_set_index[c]; + if (gain_set_index >= 0) { + if (pstr_gain_set_params[gain_set_index].drc_band_type == 1) { + band_count = pstr_gain_set_params[gain_set_index].band_count; + if (band_count > 1) { + cplx += COMPLEXITY_W_LAP * band_count; + } + } + } + } + } else { + err_code = impd_drc_init_all_filter_banks( + &pstr_uni_drc_config->str_uni_drc_config_ext.str_drc_coefficients_uni_drc_v1[0], + pstr_drc_instructions_uni_drc, &pstr_drc_gain_enc->str_filter_banks, ptr_scratch); + + if (err_code) return err_code; + + cplx += COMPLEXITY_W_IIR * pstr_drc_gain_enc->str_filter_banks.complexity; + + for (g = 0; g < pstr_drc_instructions_uni_drc->num_drc_channel_groups; g++) { + pstr_gain_modifiers = &pstr_drc_instructions_uni_drc->str_gain_modifiers[g]; + if (pstr_gain_modifiers->shape_filter_present == 1) { + cplx_tmp = 0.0f; + pstr_shape_filter_block_params = + &pstr_uni_drc_config->str_uni_drc_config_ext.str_drc_coefficients_uni_drc_v1[0] + .str_shape_filter_block_params[pstr_gain_modifiers->shape_filter_index]; + if (pstr_shape_filter_block_params->lf_cut_filter_present == 1) { + cplx_tmp += COMPLEXITY_W_SHAPE; + } + if (pstr_shape_filter_block_params->lf_boost_filter_present == 1) { + cplx_tmp += COMPLEXITY_W_SHAPE; + } + if (pstr_shape_filter_block_params->hf_cut_filter_present == 1) { + cplx_tmp += COMPLEXITY_W_SHAPE * 2.0f; + } + if (pstr_shape_filter_block_params->hf_boost_filter_present == 1) { + cplx_tmp += COMPLEXITY_W_SHAPE * 2.0f; + } + cplx += cplx_tmp * pstr_drc_instructions_uni_drc->num_channels_per_channel_group[g]; + } + } + } + + for (g = 0; g < pstr_drc_instructions_uni_drc->num_drc_channel_groups; g++) { + gain_set_index_offset = 0; + gain_set_index = -1; + for (c = 0; c < pstr_drc_instructions_uni_drc->drc_channel_count; c++) { + if (pstr_drc_instructions_uni_drc->channel_group_for_channel[c] == g) { + gain_set_index = pstr_drc_instructions_uni_drc->gain_set_index[c]; + break; + } + } + if (pstr_uni_drc_config->str_uni_drc_config_ext.drc_coefficients_uni_drc_v1_count > 0) { + gain_set_index_offset = + pstr_uni_drc_config->str_uni_drc_config_ext.str_drc_coefficients_uni_drc_v1[0] + .gain_set_count; + pstr_gain_set_params = + pstr_uni_drc_config->str_uni_drc_config_ext.str_drc_coefficients_uni_drc_v1[0] + .str_gain_set_params; + } + if (gain_set_index >= gain_set_index_offset) { + pstr_parametric_drc_instructions = NULL; + pstr_parametric_drc_gain_set_params = + &pstr_uni_drc_config->str_uni_drc_config_ext.str_drc_coeff_parametric_drc + .parametric_drc_gain_set_params[gain_set_index - gain_set_index_offset]; + for (i = 0; + i < pstr_uni_drc_config->str_uni_drc_config_ext.parametric_drc_instructions_count; + i++) { + if (pstr_parametric_drc_gain_set_params->parametric_drc_id == + pstr_uni_drc_config->str_uni_drc_config_ext.str_parametric_drc_instructions[i] + .parametric_drc_id) { + pstr_parametric_drc_instructions = + &pstr_uni_drc_config->str_uni_drc_config_ext.str_parametric_drc_instructions[i]; + break; + } + } + if (pstr_parametric_drc_instructions != NULL) { + if (pstr_parametric_drc_instructions->parametric_drc_preset_id_present) { + switch (pstr_parametric_drc_instructions->parametric_drc_preset_id) { + case 0: + case 1: + case 2: + case 3: + case 4: + parametric_drc_type = PARAM_DRC_TYPE_FF; + break; + case 5: + parametric_drc_type = PARAM_DRC_TYPE_LIM; + break; + default: + return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG; + break; + } + } else { + parametric_drc_type = pstr_parametric_drc_instructions->parametric_drc_type; + } + } + channel_count_side_chain = pstr_drc_instructions_uni_drc->num_channels_per_channel_group[g]; + if (pstr_parametric_drc_gain_set_params->side_chain_config_type == 1) { + channel_count_temp = 0; + if (pstr_parametric_drc_gain_set_params->downmix_id == 0x0) { + channel_count_drom_downmix_id = pstr_uni_drc_config->str_channel_layout.base_ch_count; + } else if (pstr_parametric_drc_gain_set_params->downmix_id == 0x7F) { + channel_count_drom_downmix_id = 1; + } else { + for (i = 0; i < pstr_uni_drc_config->downmix_instructions_count; i++) { + if (pstr_parametric_drc_gain_set_params->downmix_id == + pstr_uni_drc_config->str_downmix_instructions[i].downmix_id) { + break; + } + } + if (i == pstr_uni_drc_config->downmix_instructions_count) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG; + } + channel_count_drom_downmix_id = + pstr_uni_drc_config->str_downmix_instructions[i].target_ch_count; + } + + for (i = 0; i < channel_count_drom_downmix_id; i++) { + if (pstr_parametric_drc_gain_set_params->level_estim_channel_weight[i] != 0) { + channel_count_temp++; + } + } + channel_count_side_chain = channel_count_temp; + } + if (pstr_parametric_drc_instructions != NULL) { + if (pstr_drc_gain_enc->domain == TIME_DOMAIN) { + if (parametric_drc_type == PARAM_DRC_TYPE_FF) { + weighting_filter_order = 2; + if (pstr_parametric_drc_instructions->parametric_drc_preset_id_present == 0) { + if (pstr_parametric_drc_instructions->str_parametric_drc_type_feed_forward + .level_estim_k_weighting_type == 0) { + weighting_filter_order = 0; + } else if (pstr_parametric_drc_instructions->str_parametric_drc_type_feed_forward + .level_estim_k_weighting_type == 1) { + weighting_filter_order = 1; + } + } + cplx += channel_count_side_chain * + (COMPLEXITY_W_PARAM_DRC_FILT * weighting_filter_order + 1) + + 3; + } else if (parametric_drc_type == PARAM_DRC_TYPE_LIM) { + ratio = 1.0f; + if (pstr_parametric_drc_instructions->parametric_drc_look_ahead_present == 1) { + ratio = (FLOAT32)pstr_parametric_drc_instructions->parametric_drc_look_ahead / + (FLOAT32)PARAM_DRC_TYPE_LIM_ATTACK_DEFAULT; + } + cplx += (FLOAT32)(channel_count_side_chain * COMPLEXITY_W_PARAM_LIM_FILT + + COMPLEXITY_W_PARAM_DRC_ATTACK * sqrt(ratio)); + } + } else { + if (parametric_drc_type == PARAM_DRC_TYPE_FF) { + cplx += channel_count_side_chain * COMPLEXITY_W_PARAM_DRC_SUBBAND; + } + } + } + } else { + if (pstr_drc_gain_enc->domain == TIME_DOMAIN && pstr_gain_set_params != NULL) { + if (pstr_gain_set_params[gain_set_index].gain_interpolation_type == + GAIN_INTERPOLATION_TYPE_SPLINE) { + cplx += COMPLEXITY_W_SPLINE; + } + if (pstr_gain_set_params[gain_set_index].gain_interpolation_type == + GAIN_INTERPOLATION_TYPE_LINEAR) { + cplx += COMPLEXITY_W_LINEAR; + } + } + } + } + + if (pstr_drc_instructions_uni_drc->downmix_id == 0x7F) { + channel_count = pstr_uni_drc_config->str_channel_layout.base_ch_count; + } + + cplx = (FLOAT32)(log10(cplx / channel_count) / log10(2.0f)); + pstr_drc_instructions_uni_drc->drc_set_complexity_level = (WORD32)MAX(0, ceil(cplx)); + + if (pstr_drc_instructions_uni_drc->drc_set_complexity_level > DRC_COMPLEXITY_LEVEL_MAX) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG; + } + + return IA_NO_ERROR; +} + +static IA_ERRORCODE impd_drc_get_eq_complexity_level( + ia_drc_uni_drc_config_ext_struct *pstr_uni_drc_config_ext, + ia_drc_gain_enc_struct *pstr_drc_params, ia_drc_eq_instructions_struct *pstr_eq_instructions, + VOID *ptr_scratch, WORD32 *scratch_used) { + IA_ERRORCODE err_code = IA_NO_ERROR; + WORD32 subband_domain_mode; + ia_drc_eq_set_struct *pstr_eq_set = &pstr_drc_params->str_eq_set; + + if ((pstr_drc_params->domain == TIME_DOMAIN) && + (pstr_eq_instructions->td_filter_cascade_present == 0) && + (pstr_eq_instructions->subband_gains_present == 0)) { + pstr_eq_instructions->eq_set_complexity_level = 0; + return err_code; + } + + subband_domain_mode = SUBBAND_DOMAIN_MODE_OFF; + if (pstr_eq_instructions->subband_gains_present == 1) { + subband_domain_mode = SUBBAND_DOMAIN_MODE_QMF64; + } + memset(pstr_eq_set, 0, sizeof(ia_drc_eq_set_struct)); + + err_code = impd_drc_derive_eq_set(&pstr_uni_drc_config_ext->str_eq_coefficients, + pstr_eq_instructions, (FLOAT32)pstr_drc_params->sample_rate, + pstr_drc_params->drc_frame_size, subband_domain_mode, + pstr_eq_set, ptr_scratch, scratch_used); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + + err_code = + impd_drc_get_eq_complexity(pstr_eq_set, &pstr_eq_instructions->eq_set_complexity_level); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + + return err_code; +} + +static WORD32 impd_drc_encode_downmix_coefficient(FLOAT32 downmix_coeff, FLOAT32 downmix_offset) { + WORD32 idx, code; + FLOAT32 coeff_db; + const FLOAT32 *coeff_table; + + coeff_table = impd_drc_downmix_coeff_v1; + coeff_db = 20.0f * (FLOAT32)log10(downmix_coeff) - downmix_offset; + + if (coeff_db >= coeff_table[30]) { + idx = 0; + while (coeff_db < coeff_table[idx]) { + idx++; + } + if ((idx > 0) && (coeff_db > 0.5f * (coeff_table[idx - 1] + coeff_table[idx]))) { + idx--; + } + code = idx; + } else { + code = 31; + } + + return code; +} + +static VOID impd_drc_dec_write_downmix_coeff_v1(ia_bit_buf_struct *it_bit_buf, + const FLOAT32 downmix_coeff[], + const WORD32 base_ch_count, + const WORD32 target_ch_count, + WORD32 *ptr_bit_cnt) { + LOOPIDX i, j; + WORD32 bs_downmix_offset = 0, code; + WORD32 bit_cnt_local = 0; + FLOAT32 downmix_offset[3]; + FLOAT32 tmp; + FLOAT32 quant_err, quant_err_min; + const FLOAT32 *coeff_table; + + coeff_table = impd_drc_downmix_coeff_v1; + tmp = (FLOAT32)log10((FLOAT32)target_ch_count / (FLOAT32)base_ch_count); + downmix_offset[0] = 0.0f; + downmix_offset[1] = (FLOAT32)(0.5f * floor(0.5f + 20.0f * tmp)); + downmix_offset[2] = (FLOAT32)(0.5f * floor(0.5f + 40.0f * tmp)); + + quant_err_min = 1000.0f; + for (i = 0; i < 3; i++) { + quant_err = 0.0f; + for (j = 0; j < (target_ch_count * base_ch_count); j++) { + code = impd_drc_encode_downmix_coefficient(downmix_coeff[j], downmix_offset[i]); + quant_err += (FLOAT32)fabs(20.0f * log10(downmix_coeff[j]) - + (coeff_table[code] + downmix_offset[i])); + } + if (quant_err_min > quant_err) { + quant_err_min = quant_err; + bs_downmix_offset = i; + } + } + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bs_downmix_offset, 4); + + for (j = 0; j < target_ch_count * base_ch_count; j++) { + code = + impd_drc_encode_downmix_coefficient(downmix_coeff[j], downmix_offset[bs_downmix_offset]); + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 5); + } + + *ptr_bit_cnt += bit_cnt_local; +} + +static VOID impd_drc_enc_downmix_coeff(const FLOAT32 downmix_coeff_var, + const WORD32 is_lfe_channel, WORD32 *code_size, + WORD32 *code) { + LOOPIDX idx; + const FLOAT32 *coeff_table; + FLOAT32 coeff_db; + + coeff_db = 20.0f * (FLOAT32)log10(downmix_coeff_var); + + if (is_lfe_channel == TRUE) { + coeff_table = impd_drc_downmix_coeff_lfe; + } else { + coeff_table = impd_drc_downmix_coeff; + } + if (coeff_db >= coeff_table[14]) { + idx = 0; + while (coeff_db < coeff_table[idx]) { + idx++; + } + if ((idx > 0) && (coeff_db > 0.5f * (coeff_table[idx - 1] + coeff_table[idx]))) { + idx--; + } + *code = idx; + } else { + *code = 15; + } + + *code_size = 4; +} + +static VOID impd_drc_enc_peak(const FLOAT32 peak_level, WORD32 *code, WORD32 *code_size) { + WORD32 bits; + + bits = ((WORD32)(0.5f + 32.0f * (20.0f - peak_level) + 10000.0f)) - 10000; + bits = MIN(0x0FFF, bits); + bits = MAX(0x1, bits); + + *code = bits; + *code_size = 12; +} + +static IA_ERRORCODE impd_drc_enc_method_value(const WORD32 method_definition, + const FLOAT32 method_value, WORD32 *code_size, + WORD32 *code) { + WORD32 bits; + switch (method_definition) { + case METHOD_DEFINITION_UNKNOWN_OTHER: + case METHOD_DEFINITION_PROGRAM_LOUDNESS: + case METHOD_DEFINITION_ANCHOR_LOUDNESS: + case METHOD_DEFINITION_MAX_OF_LOUDNESS_RANGE: + case METHOD_DEFINITION_MOMENTARY_LOUDNESS_MAX: + case METHOD_DEFINITION_SHORT_TERM_LOUDNESS_MAX: + bits = ((WORD32)(0.5f + 4.0f * (method_value + 57.75f) + 10000.0f)) - 10000; + bits = MIN(0x0FF, bits); + bits = MAX(0x0, bits); + *code_size = 8; + break; + case METHOD_DEFINITION_LOUDNESS_RANGE: + if (method_value >= 121.0f) { + bits = 255; + } else if (method_value > 70.0f) { + bits = ((WORD32)((method_value - 70.0f) + 0.5f)) + 204; + } else if (method_value > 32.0f) { + bits = ((WORD32)(2.0f * (method_value - 32.0f) + 0.5f)) + 128; + } else if (method_value >= 0.0f) { + bits = (WORD32)(4.0f * method_value + 0.5f); + } else { + bits = 0; + } + *code_size = 8; + break; + case METHOD_DEFINITION_MIXING_LEVEL: + bits = (WORD32)(0.5f + method_value - 80.0f); + bits = MIN(0x1F, bits); + bits = MAX(0x0, bits); + *code_size = 5; + break; + case METHOD_DEFINITION_ROOM_TYPE: + bits = (WORD32)(0.5f + method_value); + if (bits > 0x2) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_PARAM_OUT_OF_RANGE; + } + bits = MIN(0x2, bits); + bits = MAX(0x0, bits); + *code_size = 2; + break; + case METHOD_DEFINITION_SHORT_TERM_LOUDNESS: + bits = ((WORD32)(0.5f + 2.0f * (method_value + 116.f) + 10000.0f)) - 10000; + bits = MIN(0x0FF, bits); + bits = MAX(0x0, bits); + *code_size = 8; + break; + default: { + return IA_EXHEAACE_CONFIG_FATAL_DRC_PARAM_OUT_OF_RANGE; + } + } + *code = bits; + + return IA_NO_ERROR; +} + +static VOID impd_drc_quantize_ducking_scaling( + ia_drc_ducking_modifiers_struct *pstr_ducking_modifiers) { + WORD32 mu; + FLOAT32 delta; + + if (pstr_ducking_modifiers->ducking_scaling_present) { + delta = pstr_ducking_modifiers->ducking_scaling - 1.0f; + + if (delta <= 0.0f) { + mu = -1 + (WORD32)(0.5f - 8.0f * delta); + if (mu != -1) { + mu = MIN(7, mu); + mu = MAX(0, mu); + pstr_ducking_modifiers->ducking_scaling_quantized = 1.0f - 0.125f * (1.0f + mu); + } else { + pstr_ducking_modifiers->ducking_scaling_quantized = 1.0f; + pstr_ducking_modifiers->ducking_scaling_present = FALSE; + } + } else { + mu = -1 + (WORD32)(0.5f + 8.0f * delta); + if (mu != -1) { + mu = MIN(7, mu); + mu = MAX(0, mu); + pstr_ducking_modifiers->ducking_scaling_quantized = 1.0f + 0.125f * (1.0f + mu); + } else { + pstr_ducking_modifiers->ducking_scaling_quantized = 1.0f; + pstr_ducking_modifiers->ducking_scaling_present = FALSE; + } + } + } else { + pstr_ducking_modifiers->ducking_scaling_quantized = 1.0f; + } +} + +static VOID impd_drc_enc_ducking_scaling(const FLOAT32 scaling, WORD32 *bits, + FLOAT32 *scaling_quantized, + WORD32 *remove_scaling_value) { + WORD32 mu, sigma; + FLOAT32 delta; + + delta = scaling - 1.0f; + *remove_scaling_value = FALSE; + if (delta <= 0.0f) { + mu = -1 + (WORD32)(0.5f - 8.0f * delta); + sigma = -1; + *bits = 1 << 3; + } else { + mu = -1 + (WORD32)(0.5f + 8.0f * delta); + sigma = 0; + *bits = 0; + } + if (mu != -1) { + mu = MIN(7, mu); + mu = MAX(0, mu); + *bits += mu; + if (sigma == 0) { + *scaling_quantized = 1.0f + 0.125f * (1.0f + mu); + } else { + *scaling_quantized = 1.0f - 0.125f * (1.0f + mu); + } + } else { + *scaling_quantized = 1.0f; + *remove_scaling_value = TRUE; + } +} + +static VOID impd_drc_enc_ducking_modifiers( + ia_bit_buf_struct *it_bit_buf, ia_drc_ducking_modifiers_struct *pstr_ducking_modifiers, + WORD32 *ptr_bit_cnt) { + WORD32 bits; + WORD32 remove_scaling_value; + WORD32 bit_cnt_local = 0; + + if (pstr_ducking_modifiers->ducking_scaling_present == FALSE) { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_ducking_modifiers->ducking_scaling_present, 1); + } else { + impd_drc_enc_ducking_scaling(pstr_ducking_modifiers->ducking_scaling, &bits, + &(pstr_ducking_modifiers->ducking_scaling_quantized), + &remove_scaling_value); + + if (remove_scaling_value) { + pstr_ducking_modifiers->ducking_scaling_present = FALSE; + } + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_ducking_modifiers->ducking_scaling_present, 1); + + if (pstr_ducking_modifiers->ducking_scaling_present) { + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bits, 4); + } + } + + *ptr_bit_cnt += bit_cnt_local; +} + +static VOID impd_drc_enc_gain_modifiers(ia_bit_buf_struct *it_bit_buf, const WORD32 version, + const WORD32 band_count, + ia_drc_gain_modifiers_struct *pstr_gain_modifiers, + WORD32 *ptr_bit_cnt) { + LOOPIDX idx; + WORD32 tmp, sign; + WORD32 bit_cnt_local = 0; + + if (version == 1) { + for (idx = 0; idx < band_count; idx++) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_gain_modifiers->target_characteristic_left_present[idx], 1); + if (pstr_gain_modifiers->target_characteristic_left_present[idx]) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_gain_modifiers->target_characteristic_left_index[idx], 4); + } + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_gain_modifiers->target_characteristic_right_present[idx], 1); + if (pstr_gain_modifiers->target_characteristic_right_present[idx]) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_gain_modifiers->target_characteristic_right_index[idx], 4); + } + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_gain_modifiers->gain_scaling_present[idx], 1); + if (pstr_gain_modifiers->gain_scaling_present[idx]) { + tmp = (WORD32)(0.5f + 8.0f * pstr_gain_modifiers->attenuation_scaling[idx]); + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, tmp, 4); + + tmp = (WORD32)(0.5f + 8.0f * pstr_gain_modifiers->amplification_scaling[idx]); + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, tmp, 4); + } + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_gain_modifiers->gain_offset_present[idx], 1); + if (pstr_gain_modifiers->gain_offset_present[idx]) { + if (pstr_gain_modifiers->gain_offset[idx] >= 0.0f) { + tmp = (WORD32)(0.5f + MAX(0.0f, 4.0f * pstr_gain_modifiers->gain_offset[idx] - 1.0f)); + sign = 0; + } else { + tmp = (WORD32)(0.5f + MAX(0.0f, -4.0f * pstr_gain_modifiers->gain_offset[idx] - 1.0f)); + sign = 1; + } + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, sign, 1); + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, tmp, 5); + } + } + if (band_count == 1) { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_gain_modifiers->shape_filter_present, 1); + if (pstr_gain_modifiers->shape_filter_present) { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_gain_modifiers->shape_filter_index, 4); + } + } + } else if (version == 0) { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_gain_modifiers->gain_scaling_present[0], 1); + + if (pstr_gain_modifiers->gain_scaling_present[0]) { + tmp = (WORD32)(0.5f + 8.0f * pstr_gain_modifiers->attenuation_scaling[0]); + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, tmp, 4); + + tmp = (WORD32)(0.5f + 8.0f * pstr_gain_modifiers->amplification_scaling[0]); + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, tmp, 4); + } + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_gain_modifiers->gain_offset_present[0], 1); + if (pstr_gain_modifiers->gain_offset_present[0]) { + if (pstr_gain_modifiers->gain_offset[0] >= 0.0f) { + tmp = (WORD32)(0.5f + MAX(0.0f, 4.0f * pstr_gain_modifiers->gain_offset[0] - 1.0f)); + sign = 0; + } else { + tmp = (WORD32)(0.5f + MAX(0.0f, -4.0f * pstr_gain_modifiers->gain_offset[0] - 1.0f)); + sign = 1; + } + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, sign, 1); + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, tmp, 5); + } + } + + *ptr_bit_cnt += bit_cnt_local; +} + +static IA_ERRORCODE impd_drc_write_loudness_measure( + ia_bit_buf_struct *it_bit_buf, ia_drc_loudness_measure_struct *pstr_loudness_measure, + WORD32 *ptr_bit_cnt) { + IA_ERRORCODE err_code = IA_NO_ERROR; + WORD32 code, code_size; + WORD32 bit_cnt_local = 0; + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_loudness_measure->method_definition, 4); + + err_code = impd_drc_enc_method_value(pstr_loudness_measure->method_definition, + pstr_loudness_measure->method_value, &code_size, &code); + if (err_code) return (err_code); + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, (UWORD8)code_size); + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_loudness_measure->measurement_system, 4); + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_loudness_measure->reliability, 2); + + *ptr_bit_cnt += bit_cnt_local; + + return IA_NO_ERROR; +} + +static IA_ERRORCODE impd_drc_write_loudness_info(ia_bit_buf_struct *it_bit_buf, + const WORD32 version, + ia_drc_loudness_info_struct *pstr_loudness_info, + WORD32 *ptr_bit_cnt) { + IA_ERRORCODE err_code = IA_NO_ERROR; + LOOPIDX idx; + WORD32 code, code_size; + WORD32 bit_cnt_local = 0; + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_loudness_info->drc_set_id, 6); + if (version >= 1) { + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_loudness_info->eq_set_id, 6); + } + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_loudness_info->downmix_id, 7); + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_loudness_info->sample_peak_level_present, 1); + if (pstr_loudness_info->sample_peak_level_present) { + impd_drc_enc_peak(pstr_loudness_info->sample_peak_level, &code, &code_size); + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, (UWORD8)code_size); + } + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_loudness_info->true_peak_level_present, 1); + if (pstr_loudness_info->true_peak_level_present) { + impd_drc_enc_peak(pstr_loudness_info->true_peak_level, &code, &code_size); + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, (UWORD8)code_size); + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_loudness_info->true_peak_level_measurement_system, 4); + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_loudness_info->true_peak_level_reliability, 2); + } + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_loudness_info->measurement_count, 4); + + for (idx = 0; idx < pstr_loudness_info->measurement_count; idx++) { + err_code = impd_drc_write_loudness_measure( + it_bit_buf, &(pstr_loudness_info->str_loudness_measure[idx]), &bit_cnt_local); + + if (err_code) return (err_code); + } + + *ptr_bit_cnt += bit_cnt_local; + + return IA_NO_ERROR; +} + +static IA_ERRORCODE impd_drc_write_drc_instruct_uni_drc( + ia_bit_buf_struct *it_bit_buf, const WORD32 version, + ia_drc_uni_drc_config_struct *pstr_uni_drc_config, ia_drc_gain_enc_struct *pstr_gain_enc, + ia_drc_instructions_uni_drc *pstr_drc_instructions_uni_drc, VOID *ptr_scratch, + WORD32 *ptr_bit_cnt) { + IA_ERRORCODE err_code = IA_NO_ERROR; + LOOPIDX i, j, n; + WORD32 g, k, tmp, tmp_2, match, channel_count; + WORD32 bs_sequence_index, sequence_index_prev, repeat_sequence_count; + WORD32 ducking_sequence, index; + WORD32 repeat_parameters_count; + WORD32 bit_cnt_local = 0; + WORD32 band_count = 0; + WORD32 *unique_index; + FLOAT32 *unique_scaling; + FLOAT32 ducking_scaling_quantized_prev, factor; + ia_drc_ducking_modifiers_struct *pstr_ducking_modifiers; + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_drc_instructions_uni_drc->drc_set_id, 6); + if (version == 1) { + err_code = impd_drc_get_drc_complexity_level(pstr_uni_drc_config, pstr_gain_enc, + pstr_drc_instructions_uni_drc, ptr_scratch); + if (err_code & IA_FATAL_ERROR) { + return (err_code); + } + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_drc_instructions_uni_drc->drc_set_complexity_level, 4); + } + + unique_index = (WORD32 *)ptr_scratch; + unique_scaling = + (FLOAT32 *)((UWORD8 *)ptr_scratch + (MAX_CHANNEL_COUNT) * sizeof(unique_index[0])); + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_drc_instructions_uni_drc->drc_location, 4); + + if (version != 1) { + pstr_drc_instructions_uni_drc->downmix_id_present = 1; + } else { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_drc_instructions_uni_drc->downmix_id_present, 1); + } + + if (pstr_drc_instructions_uni_drc->downmix_id_present != 1) { + pstr_drc_instructions_uni_drc->downmix_id = 0; + } else { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_drc_instructions_uni_drc->downmix_id, 7); + if (version == 1) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_drc_instructions_uni_drc->drc_apply_to_downmix, 1); + } + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_drc_instructions_uni_drc->additional_downmix_id_present, 1); + + if (pstr_drc_instructions_uni_drc->additional_downmix_id_present) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_drc_instructions_uni_drc->additional_downmix_id_count, 3); + for (i = 0; i < pstr_drc_instructions_uni_drc->additional_downmix_id_count; i++) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_drc_instructions_uni_drc->additional_downmix_id[i], 7); + } + } else { + pstr_drc_instructions_uni_drc->additional_downmix_id_count = 0; + } + } + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_drc_instructions_uni_drc->drc_set_effect, 16); + + if ((pstr_drc_instructions_uni_drc->drc_set_effect & + (EFFECT_BIT_DUCK_OTHER | EFFECT_BIT_DUCK_SELF)) == 0) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_drc_instructions_uni_drc->limiter_peak_target_present, 1); + if (pstr_drc_instructions_uni_drc->limiter_peak_target_present) { + tmp = (WORD32)(0.5f - 8.0f * pstr_drc_instructions_uni_drc->limiter_peak_target); + tmp = MAX(0, tmp); + tmp = MIN(0xFF, tmp); + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, tmp, 8); + } + } + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_drc_instructions_uni_drc->drc_set_target_loudness_present, 1); + + if (pstr_drc_instructions_uni_drc->drc_set_target_loudness_present == 1) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_drc_instructions_uni_drc->drc_set_target_loudness_value_upper + 63, 6); + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_drc_instructions_uni_drc->drc_set_target_loudness_value_lower_present, + 1); + if (pstr_drc_instructions_uni_drc->drc_set_target_loudness_value_lower_present == 1) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_drc_instructions_uni_drc->drc_set_target_loudness_value_lower + 63, 6); + } + } + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_drc_instructions_uni_drc->depends_on_drc_set_present, 1); + + if (pstr_drc_instructions_uni_drc->depends_on_drc_set_present) { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_drc_instructions_uni_drc->depends_on_drc_set, 6); + } else { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_drc_instructions_uni_drc->no_independent_use, 1); + } + + if (version == 1) { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_drc_instructions_uni_drc->requires_eq, 1); + } + + channel_count = pstr_uni_drc_config->str_channel_layout.base_ch_count; + if (pstr_drc_instructions_uni_drc->drc_set_effect & + (EFFECT_BIT_DUCK_OTHER | EFFECT_BIT_DUCK_SELF)) { + i = 0; + while (i < channel_count) { + pstr_ducking_modifiers = pstr_drc_instructions_uni_drc->str_ducking_modifiers_for_channel; + bs_sequence_index = pstr_drc_instructions_uni_drc->gain_set_index[i] + 1; + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bs_sequence_index, 6); + + impd_drc_enc_ducking_modifiers(it_bit_buf, &(pstr_ducking_modifiers[i]), &bit_cnt_local); + + sequence_index_prev = pstr_drc_instructions_uni_drc->gain_set_index[i]; + ducking_scaling_quantized_prev = pstr_ducking_modifiers[i].ducking_scaling_quantized; + i++; + + if (i < channel_count) { + impd_drc_quantize_ducking_scaling(&(pstr_ducking_modifiers[i])); + } + + repeat_parameters_count = 0; + while ((i < channel_count) && (repeat_parameters_count <= 32) && + (sequence_index_prev == pstr_drc_instructions_uni_drc->gain_set_index[i]) && + (ducking_scaling_quantized_prev == + pstr_ducking_modifiers[i].ducking_scaling_quantized)) { + repeat_parameters_count++; + i++; + if (i < channel_count) { + impd_drc_quantize_ducking_scaling(&(pstr_ducking_modifiers[i])); + } + } + if (repeat_parameters_count <= 0) { + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, 0, 1); + } else { + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, 1, 1); + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, repeat_parameters_count - 1, 5); + } + } + for (j = 0; j < MAX_CHANNEL_COUNT; j++) { + unique_index[j] = -10; + unique_scaling[j] = -10.0f; + } + + ducking_sequence = -1; + g = 0; + + if (pstr_drc_instructions_uni_drc->drc_set_effect & EFFECT_BIT_DUCK_SELF) { + for (j = 0; j < channel_count; j++) { + match = FALSE; + index = pstr_drc_instructions_uni_drc->gain_set_index[j]; + factor = + pstr_drc_instructions_uni_drc->str_ducking_modifiers_for_channel[j].ducking_scaling; + for (n = 0; n < g; n++) { + if ((index >= 0) && (unique_index[n] == index) && (unique_scaling[n] == factor)) { + match = TRUE; + break; + } + } + if (match == FALSE) { + if (index >= 0) { + unique_index[g] = index; + unique_scaling[g] = factor; + g++; + } + } + } + pstr_drc_instructions_uni_drc->num_drc_channel_groups = g; + } else if (pstr_drc_instructions_uni_drc->drc_set_effect & EFFECT_BIT_DUCK_OTHER) { + for (j = 0; j < channel_count; j++) { + match = FALSE; + index = pstr_drc_instructions_uni_drc->gain_set_index[j]; + factor = + pstr_drc_instructions_uni_drc->str_ducking_modifiers_for_channel[j].ducking_scaling; + for (n = 0; n < g; n++) { + if (((index >= 0) && (unique_index[n] == index)) || + ((index < 0) && (unique_scaling[n] == factor))) { + match = TRUE; + break; + } + } + if (match == FALSE) { + if (index < 0) { + unique_index[g] = index; + unique_scaling[g] = factor; + g++; + } else { + if ((ducking_sequence > 0) && (ducking_sequence != index)) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG; + } + ducking_sequence = index; + } + } + } + pstr_drc_instructions_uni_drc->num_drc_channel_groups = g; + if (ducking_sequence < 0) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG; + } + } + + for (g = 0; g < pstr_drc_instructions_uni_drc->num_drc_channel_groups; g++) { + if (pstr_drc_instructions_uni_drc->drc_set_effect & EFFECT_BIT_DUCK_SELF) { + pstr_drc_instructions_uni_drc->gain_set_index_for_channel_group[g] = unique_index[g]; + } else if (pstr_drc_instructions_uni_drc->drc_set_effect & EFFECT_BIT_DUCK_OTHER) { + pstr_drc_instructions_uni_drc->gain_set_index_for_channel_group[g] = -1; + } + + pstr_drc_instructions_uni_drc->str_ducking_modifiers_for_channel_group[g].ducking_scaling = + unique_scaling[g]; + if (unique_scaling[g] == 1.0f) { + pstr_drc_instructions_uni_drc->str_ducking_modifiers_for_channel_group[g] + .ducking_scaling_present = FALSE; + } else { + pstr_drc_instructions_uni_drc->str_ducking_modifiers_for_channel_group[g] + .ducking_scaling_present = TRUE; + } + } + } else { + if ((version == 0 || pstr_drc_instructions_uni_drc->drc_apply_to_downmix != 0) && + ((pstr_drc_instructions_uni_drc->downmix_id == 0x7F) || + (pstr_drc_instructions_uni_drc->additional_downmix_id_count != 0))) { + channel_count = 1; + } else if ((version == 0 || pstr_drc_instructions_uni_drc->drc_apply_to_downmix != 0) && + (pstr_drc_instructions_uni_drc->downmix_id != 0) && + (pstr_drc_instructions_uni_drc->downmix_id != 0x7F) && + (pstr_drc_instructions_uni_drc->additional_downmix_id_count == 0)) { + for (i = 0; i < pstr_uni_drc_config->downmix_instructions_count; i++) { + if (pstr_drc_instructions_uni_drc->downmix_id == + pstr_uni_drc_config->str_downmix_instructions[i].downmix_id) { + break; + } + } + if (i == pstr_uni_drc_config->downmix_instructions_count) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG; + } + channel_count = pstr_uni_drc_config->str_downmix_instructions[i].target_ch_count; + } + + i = 0; + while (i < channel_count) { + bs_sequence_index = pstr_drc_instructions_uni_drc->gain_set_index[i] + 1; + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bs_sequence_index, 6); + sequence_index_prev = pstr_drc_instructions_uni_drc->gain_set_index[i]; + i++; + + repeat_sequence_count = 0; + while ((i < channel_count) && + (sequence_index_prev == pstr_drc_instructions_uni_drc->gain_set_index[i]) && + (repeat_sequence_count <= 32)) { + repeat_sequence_count++; + i++; + } + if (repeat_sequence_count <= 0) { + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, 0, 1); + } else { + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, 1, 1); + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, repeat_sequence_count - 1, 5); + } + } + for (i = 0; i < MAX_CHANNEL_COUNT; i++) { + unique_index[i] = -1; + } + + k = 0; + for (i = 0; i < channel_count; i++) { + tmp_2 = pstr_drc_instructions_uni_drc->gain_set_index[i]; + if (tmp_2 >= 0) { + match = FALSE; + for (n = 0; n < k; n++) { + if (unique_index[n] == tmp_2) { + match = TRUE; + } + } + if (match == FALSE) { + unique_index[k] = tmp_2; + k++; + } + } + } + pstr_drc_instructions_uni_drc->num_drc_channel_groups = k; + for (i = 0; i < pstr_drc_instructions_uni_drc->num_drc_channel_groups; i++) { + band_count = 0; + pstr_drc_instructions_uni_drc->gain_set_index_for_channel_group[i] = unique_index[i]; + + if (pstr_uni_drc_config->str_uni_drc_config_ext.drc_coefficients_uni_drc_v1_count > 0) { + band_count = + pstr_uni_drc_config->str_uni_drc_config_ext.str_drc_coefficients_uni_drc_v1[0] + .str_gain_set_params[pstr_drc_instructions_uni_drc + ->gain_set_index_for_channel_group[i]] + .band_count; + } else if (pstr_uni_drc_config->drc_coefficients_uni_drc_count > 0) { + band_count = pstr_uni_drc_config->str_drc_coefficients_uni_drc[0] + .str_gain_set_params[pstr_drc_instructions_uni_drc + ->gain_set_index_for_channel_group[i]] + .band_count; + } + + impd_drc_enc_gain_modifiers(it_bit_buf, version, band_count, + &(pstr_drc_instructions_uni_drc->str_gain_modifiers[i]), + &bit_cnt_local); + } + } + + *ptr_bit_cnt += bit_cnt_local; + return err_code; +} + +static VOID impd_drc_write_gain_params(ia_bit_buf_struct *it_bit_buf, const WORD32 version, + const WORD32 band_count, const WORD32 drc_band_type, + ia_drc_gain_params_struct *pstr_gain_params, + WORD32 *ptr_bit_cnt) { + LOOPIDX idx; + WORD32 bit_cnt_local = 0; + + if (version != 1) { + for (idx = 0; idx < band_count; idx++) { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_gain_params[idx].drc_characteristic, 7); + } + } else { + WORD32 index_present; + WORD32 gain_sequence_index_last = -100; + for (idx = 0; idx < band_count; idx++) { + if (pstr_gain_params[idx].gain_sequence_index == gain_sequence_index_last + 1) { + index_present = 0; + } else { + index_present = 1; + } + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, index_present, 1); + + if (index_present == 1) { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_gain_params[idx].gain_sequence_index, 6); + gain_sequence_index_last = pstr_gain_params[idx].gain_sequence_index; + } + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_gain_params[idx].drc_characteristic_present, 1); + if (pstr_gain_params[idx].drc_characteristic_present) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_gain_params[idx].drc_characteristic_format_is_cicp, 1); + if (pstr_gain_params[idx].drc_characteristic_format_is_cicp == 1) { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_gain_params[idx].drc_characteristic, 7); + } else { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_gain_params[idx].drc_characteristic_left_index, 4); + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_gain_params[idx].drc_characteristic_right_index, 4); + } + } + } + } + + for (idx = 1; idx < band_count; idx++) { + if (drc_band_type) { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_gain_params[idx].crossover_freq_index, 4); + } else { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_gain_params[idx].start_sub_band_index, 10); + } + } + + *ptr_bit_cnt += bit_cnt_local; +} + +static VOID impd_drc_write_gain_set_params(ia_bit_buf_struct *it_bit_buf, const WORD32 version, + ia_drc_gain_set_params_struct *pstr_gain_set_params, + WORD32 *ptr_bit_cnt) { + WORD32 bit_cnt_local = 0; + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_gain_set_params->gain_coding_profile, 2); + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_gain_set_params->gain_interpolation_type, 1); + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_gain_set_params->full_frame, 1); + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_gain_set_params->time_alignment, 1); + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_gain_set_params->time_delta_min_present, 1); + + if (pstr_gain_set_params->time_delta_min_present) { + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_gain_set_params->delta_tmin - 1, 11); + } + if (pstr_gain_set_params->gain_coding_profile != GAIN_CODING_PROFILE_CONSTANT) { + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_gain_set_params->band_count, 4); + if (pstr_gain_set_params->band_count > 1) { + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_gain_set_params->drc_band_type, 1); + } + + impd_drc_write_gain_params(it_bit_buf, version, pstr_gain_set_params->band_count, + pstr_gain_set_params->drc_band_type, + pstr_gain_set_params->gain_params, &bit_cnt_local); + } + + *ptr_bit_cnt += bit_cnt_local; +} + +static VOID impd_drc_write_split_drc_characteristic( + ia_bit_buf_struct *it_bit_buf, const WORD32 side, + ia_drc_split_drc_characteristic_struct *pstr_split_characteristic, WORD32 *ptr_bit_cnt) { + LOOPIDX idx; + WORD32 bs_node_gain, bs_node_level_delta; + WORD32 bit_cnt_local = 0; + FLOAT32 bs_node_level_previous; + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_split_characteristic->characteristic_format, 1); + + if (pstr_split_characteristic->characteristic_format != 0) { + bs_node_level_previous = DRC_INPUT_LOUDNESS_TARGET; + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_split_characteristic->characteristic_node_count - 1, 2); + + for (idx = 1; idx <= pstr_split_characteristic->characteristic_node_count; idx++) { + bs_node_level_delta = (WORD32)(floor(fabs(pstr_split_characteristic->node_level[idx] - + bs_node_level_previous) + + 0.5f) - + 1); + + if (bs_node_level_delta < 0) { + bs_node_level_delta = 0; + } + if (bs_node_level_delta > 31) { + bs_node_level_delta = 31; + } + if (side == RIGHT_SIDE) { + bs_node_level_previous = bs_node_level_previous + (bs_node_level_delta + 1); + } else { + bs_node_level_previous = bs_node_level_previous - (bs_node_level_delta + 1); + } + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bs_node_level_delta, 5); + + bs_node_gain = + (WORD32)floor((pstr_split_characteristic->node_gain[idx] + 64.0f) * 2.0f + 0.5f); + + if (bs_node_gain < 0) { + bs_node_gain = 0; + } + if (bs_node_gain > 255) { + bs_node_gain = 255; + } + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bs_node_gain, 8); + } + } else { + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_split_characteristic->bs_gain, 6); + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_split_characteristic->bs_io_ratio, 4); + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_split_characteristic->bs_exp, 4); + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_split_characteristic->flip_sign, 1); + } + + *ptr_bit_cnt += bit_cnt_local; +} + +static VOID impd_drc_write_shape_filter_block_params( + ia_bit_buf_struct *it_bit_buf, + ia_drc_shape_filter_block_params_struct *pstr_shape_filter_block_params, + WORD32 *ptr_bit_cnt) { + WORD32 bit_cnt_local = 0; + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_shape_filter_block_params->lf_cut_filter_present, 1); + if (pstr_shape_filter_block_params->lf_cut_filter_present == 1) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_shape_filter_block_params->str_lf_cut_params.corner_freq_index, 3); + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_shape_filter_block_params->str_lf_cut_params.filter_strength_index, 2); + } + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_shape_filter_block_params->lf_boost_filter_present, 1); + if (pstr_shape_filter_block_params->lf_boost_filter_present == 1) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_shape_filter_block_params->str_lf_boost_params.corner_freq_index, 3); + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_shape_filter_block_params->str_lf_boost_params.filter_strength_index, 2); + } + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_shape_filter_block_params->hf_cut_filter_present, 1); + if (pstr_shape_filter_block_params->hf_cut_filter_present == 1) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_shape_filter_block_params->str_hf_cut_params.corner_freq_index, 3); + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_shape_filter_block_params->str_hf_cut_params.filter_strength_index, 2); + } + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_shape_filter_block_params->hf_boost_filter_present, 1); + if (pstr_shape_filter_block_params->hf_boost_filter_present == 1) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_shape_filter_block_params->str_hf_boost_params.corner_freq_index, 3); + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_shape_filter_block_params->str_hf_boost_params.filter_strength_index, 2); + } + + *ptr_bit_cnt += bit_cnt_local; +} + +static VOID impd_drc_write_drc_coeff_uni_drc( + ia_bit_buf_struct *it_bit_buf, const WORD32 version, + ia_drc_coefficients_uni_drc_struct *pstr_drc_coefficients_uni_drc, WORD32 *ptr_bit_cnt) { + LOOPIDX idx; + WORD32 bit_cnt_local = 0; + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_drc_coefficients_uni_drc->drc_location, 4); + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_drc_coefficients_uni_drc->drc_frame_size_present, 1); + + if (pstr_drc_coefficients_uni_drc->drc_frame_size_present) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, (pstr_drc_coefficients_uni_drc->drc_frame_size - 1), 15); + } + + if (version != 1) { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_drc_coefficients_uni_drc->gain_set_count, 6); + + for (idx = 0; idx < pstr_drc_coefficients_uni_drc->gain_set_count; idx++) { + impd_drc_write_gain_set_params(it_bit_buf, version, + &(pstr_drc_coefficients_uni_drc->str_gain_set_params[idx]), + &bit_cnt_local); + } + } else { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_drc_coefficients_uni_drc->drc_characteristic_left_present, 1); + if (pstr_drc_coefficients_uni_drc->drc_characteristic_left_present) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_drc_coefficients_uni_drc->characteristic_left_count, 4); + + for (idx = 1; idx <= pstr_drc_coefficients_uni_drc->characteristic_left_count; idx++) { + impd_drc_write_split_drc_characteristic( + it_bit_buf, LEFT_SIDE, + &pstr_drc_coefficients_uni_drc->str_split_characteristic_left[idx], &bit_cnt_local); + } + } + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_drc_coefficients_uni_drc->drc_characteristic_right_present, 1); + if (pstr_drc_coefficients_uni_drc->drc_characteristic_right_present) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_drc_coefficients_uni_drc->characteristic_right_count, 4); + for (idx = 1; idx <= pstr_drc_coefficients_uni_drc->characteristic_right_count; idx++) { + impd_drc_write_split_drc_characteristic( + it_bit_buf, RIGHT_SIDE, + &pstr_drc_coefficients_uni_drc->str_split_characteristic_right[idx], &bit_cnt_local); + } + } + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_drc_coefficients_uni_drc->shape_filters_present, 1); + if (pstr_drc_coefficients_uni_drc->shape_filters_present) { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_drc_coefficients_uni_drc->shape_filter_count, 4); + for (idx = 1; idx <= pstr_drc_coefficients_uni_drc->shape_filter_count; idx++) { + impd_drc_write_shape_filter_block_params( + it_bit_buf, &pstr_drc_coefficients_uni_drc->str_shape_filter_block_params[idx], + &bit_cnt_local); + } + } + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_drc_coefficients_uni_drc->gain_sequence_count, 6); + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_drc_coefficients_uni_drc->gain_set_count, 6); + + for (idx = 0; idx < pstr_drc_coefficients_uni_drc->gain_set_count; idx++) { + impd_drc_write_gain_set_params(it_bit_buf, version, + &(pstr_drc_coefficients_uni_drc->str_gain_set_params[idx]), + &bit_cnt_local); + } + } + + *ptr_bit_cnt += bit_cnt_local; +} + +static VOID impd_drc_write_downmix_instructions( + ia_bit_buf_struct *it_bit_buf, const WORD32 version, ia_drc_gain_enc_struct *pstr_gain_enc, + ia_drc_downmix_instructions_struct *pstr_downmix_instructions, WORD32 *ptr_bit_cnt) { + LOOPIDX idx; + WORD32 code, code_size; + WORD32 bit_cnt_local = 0; + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_downmix_instructions->downmix_id, 7); + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_downmix_instructions->target_ch_count, 7); + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_downmix_instructions->target_layout, 8); + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_downmix_instructions->downmix_coefficients_present, 1); + + if (pstr_downmix_instructions->downmix_coefficients_present) { + if (version != 1) { + WORD32 is_lfe_channel = FALSE; + for (idx = 0; + idx < (pstr_downmix_instructions->target_ch_count * pstr_gain_enc->base_ch_count); + idx++) { + impd_drc_enc_downmix_coeff(pstr_downmix_instructions->downmix_coeff[idx], is_lfe_channel, + &code_size, &code); + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, (UWORD8)code_size); + } + } else { + impd_drc_dec_write_downmix_coeff_v1( + it_bit_buf, pstr_downmix_instructions->downmix_coeff, pstr_gain_enc->base_ch_count, + pstr_downmix_instructions->target_ch_count, &bit_cnt_local); + } + } + + *ptr_bit_cnt += bit_cnt_local; +} + +static VOID impd_drc_enc_channel_weight(const FLOAT32 channel_weight_lin, WORD32 *code_size, + WORD32 *code) { + LOOPIDX idx; + FLOAT32 channel_weight_db; + const FLOAT32 *channel_weight_table; + + channel_weight_table = impd_drc_channel_weight; + channel_weight_db = 20.0f * (FLOAT32)log10(channel_weight_lin); + + if (channel_weight_db >= channel_weight_table[14]) { + idx = 0; + while (channel_weight_db < channel_weight_table[idx]) { + idx++; + } + if ((idx > 0) && (channel_weight_db > + 0.5f * (channel_weight_table[idx - 1] + channel_weight_table[idx]))) { + idx--; + } + *code = idx; + } else { + *code = 15; + } + + *code_size = 4; +} + +static IA_ERRORCODE impd_drc_write_parametric_drc_gain_set_params( + ia_bit_buf_struct *it_bit_buf, ia_drc_uni_drc_config_struct *pstr_uni_drc_config, + ia_drc_parametric_drc_gain_set_params_struct *pstr_parametric_drc_gain_set_params, + WORD32 *ptr_bit_cnt) { + LOOPIDX idx; + WORD32 code_size = 0, code = 0; + WORD32 bit_cnt_local = 0; + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_parametric_drc_gain_set_params->parametric_drc_id, 4); + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_parametric_drc_gain_set_params->side_chain_config_type, 3); + + if (pstr_parametric_drc_gain_set_params->side_chain_config_type == 1) { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_parametric_drc_gain_set_params->downmix_id, 7); + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_parametric_drc_gain_set_params->level_estim_channel_weight_format, 1); + + if (pstr_parametric_drc_gain_set_params->downmix_id == 0x7F) { + pstr_parametric_drc_gain_set_params->channel_count_drom_downmix_id = 1; + } else if (pstr_parametric_drc_gain_set_params->downmix_id == 0x0) { + pstr_parametric_drc_gain_set_params->channel_count_drom_downmix_id = + pstr_uni_drc_config->str_channel_layout.base_ch_count; + } else { + for (idx = 0; idx < pstr_uni_drc_config->downmix_instructions_count; idx++) { + if (pstr_parametric_drc_gain_set_params->downmix_id == + pstr_uni_drc_config->str_downmix_instructions[idx].downmix_id) { + break; + } + } + if (idx == pstr_uni_drc_config->downmix_instructions_count) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG; + } + pstr_parametric_drc_gain_set_params->channel_count_drom_downmix_id = + pstr_uni_drc_config->str_downmix_instructions[idx].target_ch_count; + } + + for (idx = 0; idx < pstr_parametric_drc_gain_set_params->channel_count_drom_downmix_id; + idx++) { + if (pstr_parametric_drc_gain_set_params->level_estim_channel_weight_format != 0) { + impd_drc_enc_channel_weight( + pstr_parametric_drc_gain_set_params->level_estim_channel_weight[idx], &code_size, + &code); + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, (UWORD8)code_size); + } else { + if (pstr_parametric_drc_gain_set_params->level_estim_channel_weight[idx] == 0) { + code = 0; + } else { + code = 1; + } + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 1); + } + } + } + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_parametric_drc_gain_set_params->drc_input_loudness_present, 1); + if (pstr_parametric_drc_gain_set_params->drc_input_loudness_present) { + code = ((WORD32)(0.5f + + 4.0f * (pstr_parametric_drc_gain_set_params->drc_input_loudness + 57.75f) + + 10000.0f)) - + 10000; + code = MIN(0x0FF, code); + code = MAX(0x0, code); + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 8); + } + + *ptr_bit_cnt += bit_cnt_local; + + return IA_NO_ERROR; +} + +static VOID impd_drc_write_parametric_drc_type_feed_forward( + ia_bit_buf_struct *it_bit_buf, WORD32 drc_frame_size_parametric_drc, + ia_drc_parametric_drc_type_feed_forward_struct *pstr_parametric_drc_type_feed_forward, + WORD32 *ptr_bit_cnt) { + LOOPIDX idx; + WORD32 code = 0; + WORD32 bit_cnt_local = 0; + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_parametric_drc_type_feed_forward->level_estim_k_weighting_type, 2); + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_parametric_drc_type_feed_forward->level_estim_integration_time_present, 1); + + if (pstr_parametric_drc_type_feed_forward->level_estim_integration_time_present) { + code = + (WORD32)(((FLOAT32)pstr_parametric_drc_type_feed_forward->level_estim_integration_time / + drc_frame_size_parametric_drc + + 0.5f) - + 1); + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 6); + } + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_parametric_drc_type_feed_forward->drc_curve_definition_type, 1); + if (pstr_parametric_drc_type_feed_forward->drc_curve_definition_type != 0) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_parametric_drc_type_feed_forward->node_count - 2, 3); + + for (idx = 0; idx < pstr_parametric_drc_type_feed_forward->node_count; idx++) { + if (idx == 0) { + code = -11 - pstr_parametric_drc_type_feed_forward->node_level[0]; + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 6); + } else { + code = pstr_parametric_drc_type_feed_forward->node_level[idx] - + pstr_parametric_drc_type_feed_forward->node_level[idx - 1] - 1; + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 5); + } + code = pstr_parametric_drc_type_feed_forward->node_gain[idx] + 39; + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 6); + } + } else { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_parametric_drc_type_feed_forward->drc_characteristic, 7); + } + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_parametric_drc_type_feed_forward->drc_gain_smooth_parameters_present, 1); + if (pstr_parametric_drc_type_feed_forward->drc_gain_smooth_parameters_present) { + code = (WORD32)(pstr_parametric_drc_type_feed_forward->gain_smooth_attack_time_slow * 0.2); + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 8); + + code = (WORD32)(pstr_parametric_drc_type_feed_forward->gain_smooth_release_time_slow * 0.025); + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 8); + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_parametric_drc_type_feed_forward->gain_smooth_time_fast_present, 1); + if (pstr_parametric_drc_type_feed_forward->gain_smooth_time_fast_present) { + code = (WORD32)(pstr_parametric_drc_type_feed_forward->gain_smooth_attack_time_fast * 0.2); + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 8); + + code = + (WORD32)(pstr_parametric_drc_type_feed_forward->gain_smooth_release_time_fast * 0.05); + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 8); + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_parametric_drc_type_feed_forward->gain_smooth_threshold_present, 1); + if (pstr_parametric_drc_type_feed_forward->gain_smooth_threshold_present) { + if (pstr_parametric_drc_type_feed_forward->gain_smooth_attack_threshold <= 30) { + code = pstr_parametric_drc_type_feed_forward->gain_smooth_attack_threshold; + } else { + code = 31; + } + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 5); + + if (pstr_parametric_drc_type_feed_forward->gain_smooth_release_threshold <= 30) { + code = pstr_parametric_drc_type_feed_forward->gain_smooth_release_threshold; + } else { + code = 31; + } + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 5); + } + } + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_parametric_drc_type_feed_forward->gain_smooth_hold_off_count_present, 1); + if (pstr_parametric_drc_type_feed_forward->gain_smooth_hold_off_count_present) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_parametric_drc_type_feed_forward->gain_smooth_hold_off, 7); + } + } + + *ptr_bit_cnt += bit_cnt_local; +} + +static VOID impd_drc_write_parametric_drc_type_lim( + ia_bit_buf_struct *it_bit_buf, + ia_drc_parametric_drc_type_lim_struct *pstr_parametric_drc_type_lim, WORD32 *ptr_bit_cnt) { + WORD32 temp = 0; + WORD32 bit_cnt_local = 0; + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_parametric_drc_type_lim->parametric_lim_threshold_present, 1); + if (pstr_parametric_drc_type_lim->parametric_lim_threshold_present) { + temp = (WORD32)(0.5f - 8.0f * pstr_parametric_drc_type_lim->parametric_lim_threshold); + temp = MAX(0, temp); + temp = MIN(0xFF, temp); + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, temp, 8); + } + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_parametric_drc_type_lim->parametric_lim_release_present, 1); + if (pstr_parametric_drc_type_lim->parametric_lim_release_present) { + temp = (WORD32)(pstr_parametric_drc_type_lim->parametric_lim_release * 0.1); + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, temp, 8); + } + + *ptr_bit_cnt += bit_cnt_local; +} + +static IA_ERRORCODE impd_drc_write_parametric_drc_instructions( + ia_bit_buf_struct *it_bit_buf, WORD32 drc_frame_size_parametric_drc, + ia_drc_parametric_drc_instructions_struct *pstr_parametric_drc_instructions, + WORD32 *ptr_bit_cnt) { + WORD32 bit_size = 0, len_size_bits = 0, bit_size_len = 0; + WORD32 bit_cnt_local = 0; + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_parametric_drc_instructions->parametric_drc_id, 4); + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_parametric_drc_instructions->parametric_drc_look_ahead_present, 1); + + if (pstr_parametric_drc_instructions->parametric_drc_look_ahead_present) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_parametric_drc_instructions->parametric_drc_look_ahead, 7); + } + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_parametric_drc_instructions->parametric_drc_preset_id_present, 1); + if (!(pstr_parametric_drc_instructions->parametric_drc_preset_id_present)) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_parametric_drc_instructions->parametric_drc_type, 3); + + if (pstr_parametric_drc_instructions->parametric_drc_type == PARAM_DRC_TYPE_LIM) { + impd_drc_write_parametric_drc_type_lim( + it_bit_buf, &(pstr_parametric_drc_instructions->str_parametric_drc_type_lim), + &bit_cnt_local); + } else if (pstr_parametric_drc_instructions->parametric_drc_type == PARAM_DRC_TYPE_FF) { + impd_drc_write_parametric_drc_type_feed_forward( + it_bit_buf, drc_frame_size_parametric_drc, + &(pstr_parametric_drc_instructions->str_parametric_drc_type_feed_forward), + &bit_cnt_local); + } else { + bit_size = pstr_parametric_drc_instructions->len_bit_size - 1; + len_size_bits = (WORD32)(log((FLOAT32)bit_size) / log(2.f)) + 1; + bit_size_len = len_size_bits - 4; + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bit_size_len, 4); + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bit_size, (UWORD8)bit_size); + switch (pstr_parametric_drc_instructions->parametric_drc_type) { + default: + return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG; + } + } + } else { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_parametric_drc_instructions->parametric_drc_preset_id, 7); + } + + *ptr_bit_cnt += bit_cnt_local; + + return IA_NO_ERROR; +} + +static IA_ERRORCODE impd_drc_write_drc_coeff_parametric_drc( + ia_bit_buf_struct *it_bit_buf, ia_drc_uni_drc_config_struct *pstr_uni_drc_config, + ia_drc_coeff_parametric_drc_struct *pstr_drc_coeff_parametric_drc, WORD32 *ptr_bit_cnt) { + IA_ERRORCODE err_code = IA_NO_ERROR; + LOOPIDX idx; + WORD32 bits = 0, mu = 0, nu = 0; + WORD32 bit_cnt_local = 0; + FLOAT32 exp = 0.f; + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_drc_coeff_parametric_drc->drc_location, 4); + + exp = (FLOAT32)(log(pstr_drc_coeff_parametric_drc->parametric_drc_frame_size) / log(2)); + if (exp == (FLOAT32)((WORD32)exp)) { + pstr_drc_coeff_parametric_drc->parametric_drc_frame_size_format = 0; + } else { + pstr_drc_coeff_parametric_drc->parametric_drc_frame_size_format = 1; + } + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_drc_coeff_parametric_drc->parametric_drc_frame_size_format, 1); + if (!(pstr_drc_coeff_parametric_drc->parametric_drc_frame_size_format)) { + bits = (WORD32)exp; + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bits, 4); + } else { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, (pstr_drc_coeff_parametric_drc->parametric_drc_frame_size - 1), 15); + } + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_drc_coeff_parametric_drc->parametric_drc_delay_max_present, 1); + if (pstr_drc_coeff_parametric_drc->parametric_drc_delay_max_present == 1) { + for (nu = 0; nu < 8; nu++) { + mu = pstr_drc_coeff_parametric_drc->parametric_drc_delay_max / (16 << nu); + if (mu * (16 << nu) < pstr_drc_coeff_parametric_drc->parametric_drc_delay_max) { + mu++; + } + if (mu < 32) { + break; + } + } + if (nu == 8) { + mu = 31; + nu = 7; + } + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, mu, 5); + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, nu, 3); + } + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_drc_coeff_parametric_drc->reset_parametric_drc, 1); + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_drc_coeff_parametric_drc->parametric_drc_gain_set_count, 6); + for (idx = 0; idx < pstr_drc_coeff_parametric_drc->parametric_drc_gain_set_count; idx++) { + err_code = impd_drc_write_parametric_drc_gain_set_params( + it_bit_buf, pstr_uni_drc_config, + &(pstr_drc_coeff_parametric_drc->parametric_drc_gain_set_params[idx]), &bit_cnt_local); + + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + } + + *ptr_bit_cnt += bit_cnt_local; + + return err_code; +} + +static VOID impd_drc_write_loud_eq_instructions( + ia_bit_buf_struct *it_bit_buf, ia_drc_loud_eq_instructions_struct *pstr_loud_eq_instructions, + WORD32 *ptr_bit_cnt) { + LOOPIDX idx; + WORD32 bit_cnt_local = 0; + WORD32 bs_loud_eq_offset; + WORD32 bs_loud_eq_scaling; + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_loud_eq_instructions->loud_eq_set_id, 4); + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_loud_eq_instructions->drc_location, 4); + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_loud_eq_instructions->downmix_id_present, 1); + if (pstr_loud_eq_instructions->downmix_id_present) { + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_loud_eq_instructions->downmix_id, 7); + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_loud_eq_instructions->additional_downmix_id_present, 1); + if (!(pstr_loud_eq_instructions->additional_downmix_id_present)) { + pstr_loud_eq_instructions->additional_downmix_id_count = 0; + } else { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_loud_eq_instructions->additional_downmix_id_count, 7); + for (idx = 0; idx < pstr_loud_eq_instructions->additional_downmix_id_count; idx++) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_loud_eq_instructions->additional_downmix_id[idx], 7); + } + } + } + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_loud_eq_instructions->drc_set_id_present, 1); + if (pstr_loud_eq_instructions->drc_set_id_present) { + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_loud_eq_instructions->drc_set_id, 6); + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_loud_eq_instructions->additional_drc_set_id_present, 1); + if (!(pstr_loud_eq_instructions->additional_drc_set_id_present)) { + pstr_loud_eq_instructions->additional_drc_set_id_count = 0; + } else { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_loud_eq_instructions->additional_drc_set_id_count, 6); + for (idx = 0; idx < pstr_loud_eq_instructions->additional_drc_set_id_count; idx++) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_loud_eq_instructions->additional_drc_set_id[idx], 6); + } + } + } + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_loud_eq_instructions->eq_set_id_present, 1); + if (pstr_loud_eq_instructions->eq_set_id_present) { + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_loud_eq_instructions->eq_set_id, 6); + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_loud_eq_instructions->additional_eq_set_id_present, 1); + if (!(pstr_loud_eq_instructions->additional_eq_set_id_present)) { + pstr_loud_eq_instructions->additional_eq_set_id_count = 0; + } else { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_loud_eq_instructions->additional_eq_set_id_count, 6); + for (idx = 0; idx < pstr_loud_eq_instructions->additional_eq_set_id_count; idx++) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_loud_eq_instructions->additional_eq_set_id[idx], 6); + } + } + } + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_loud_eq_instructions->loudness_after_drc, 1); + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_loud_eq_instructions->loudness_after_eq, 1); + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_loud_eq_instructions->loud_eq_gain_sequence_count, 6); + for (idx = 0; idx < pstr_loud_eq_instructions->loud_eq_gain_sequence_count; idx++) { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_loud_eq_instructions->gain_sequence_index[idx], 6); + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_loud_eq_instructions->drc_characteristic_format_is_cicp[idx], 1); + if (pstr_loud_eq_instructions->drc_characteristic_format_is_cicp[idx] == 1) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_loud_eq_instructions->drc_characteristic[idx], 7); + } else { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_loud_eq_instructions->drc_characteristic_left_index[idx], 4); + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_loud_eq_instructions->drc_characteristic_right_index[idx], 4); + } + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_loud_eq_instructions->frequency_range_index[idx], 6); + bs_loud_eq_scaling = (WORD32)floor( + 0.5f - 2.0f * INV_LOG10_2 * log10(pstr_loud_eq_instructions->loud_eq_scaling[idx])); + if (bs_loud_eq_scaling < 0) { + bs_loud_eq_scaling = 0; + } else if (bs_loud_eq_scaling > 7) { + bs_loud_eq_scaling = 7; + } + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bs_loud_eq_scaling, 3); + bs_loud_eq_offset = + (WORD32)floor(0.5f + pstr_loud_eq_instructions->loud_eq_offset[idx] / 1.5f + 16.0f); + if (bs_loud_eq_offset < 0) { + bs_loud_eq_offset = 0; + } else if (bs_loud_eq_offset > 31) { + bs_loud_eq_offset = 31; + } + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bs_loud_eq_offset, 5); + } + + *ptr_bit_cnt += bit_cnt_local; +} + +static VOID impd_drc_write_filter_element(ia_bit_buf_struct *it_bit_buf, + ia_drc_filter_element_struct *pstr_filter_element, + WORD32 *ptr_bit_cnt) { + WORD32 bs_filter_element_gain; + WORD32 bit_cnt_local = 0; + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_filter_element->filter_element_index, 6); + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_filter_element->filter_element_gain_present, 1); + if (pstr_filter_element->filter_element_gain_present) { + bs_filter_element_gain = + (WORD32)floor(0.5f + 8.0f * (pstr_filter_element->filter_element_gain + 96.0f)); + bs_filter_element_gain = MAX(0, bs_filter_element_gain); + bs_filter_element_gain = MIN(1023, bs_filter_element_gain); + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bs_filter_element_gain, 10); + } + + *ptr_bit_cnt += bit_cnt_local; +} + +static VOID impd_drc_write_filter_block(ia_bit_buf_struct *it_bit_buf, + ia_drc_filter_block_struct *pstr_filter_block, + WORD32 *ptr_bit_cnt) { + LOOPIDX idx; + WORD32 bit_cnt_local = 0; + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_filter_block->filter_element_count, 6); + for (idx = 0; idx < pstr_filter_block->filter_element_count; idx++) { + impd_drc_write_filter_element(it_bit_buf, &(pstr_filter_block->filter_element[idx]), + &bit_cnt_local); + } + + *ptr_bit_cnt += bit_cnt_local; +} + +static IA_ERRORCODE impd_drc_encode_radius(FLOAT32 radius, WORD32 *code) { + LOOPIDX idx; + FLOAT32 rho; + + if (radius < 0.0f) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG; + } + rho = 1.0f - radius; + if ((rho < 0.0f) || (rho > 1.0f)) { + if (rho < 0.0f) { + rho = 0.0f; + } + if (rho > 1.0f) { + rho = 1.0f; + } + } + if (rho > impd_drc_zero_pole_radius_table[127]) { + rho = impd_drc_zero_pole_radius_table[127]; + } + idx = 0; + while (rho > impd_drc_zero_pole_radius_table[idx]) { + idx++; + } + if (idx == 0) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG; + } + if (rho < + 0.5f * (impd_drc_zero_pole_radius_table[idx - 1] + impd_drc_zero_pole_radius_table[idx])) { + idx--; + } + *code = idx; + + return IA_NO_ERROR; +} + +static LOOPIDX impd_drc_encode_angle(FLOAT32 angle) { + LOOPIDX idx; + + if ((angle < 0.0f) || (angle > 1.0f)) { + if (angle < 0.0f) { + angle = 0.0f; + } + if (angle > 1.0f) { + angle = 1.0f; + } + } + idx = 0; + while (angle > impd_drc_zero_pole_angle_table[idx]) { + idx++; + } + if (idx == 0) { + return idx; + } + if (angle < + 0.5f * (impd_drc_zero_pole_angle_table[idx - 1] + impd_drc_zero_pole_angle_table[idx])) { + idx--; + } + + return (idx); +} + +static IA_ERRORCODE impd_drc_write_unique_td_filter_element( + ia_bit_buf_struct *it_bit_buf, + ia_drc_unique_td_filter_element_struct *pstr_unique_td_filter_element, WORD32 *ptr_bit_cnt) { + IA_ERRORCODE err_code = IA_NO_ERROR; + LOOPIDX idx; + WORD32 sign, code; + WORD32 bs_real_zero_radius_one_count; + WORD32 bs_fir_coefficient; + WORD32 bit_cnt_local = 0; + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_unique_td_filter_element->eq_filter_format, 1); + if (pstr_unique_td_filter_element->eq_filter_format != 0) { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_unique_td_filter_element->fir_filter_order, 7); + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_unique_td_filter_element->fir_symmetry, 1); + + for (idx = 0; idx < pstr_unique_td_filter_element->fir_filter_order / 2 + 1; idx++) { + if (pstr_unique_td_filter_element->fir_coefficient[idx] >= 0.0f) { + sign = 0; + } else { + sign = 1; + } + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, sign, 1); + + bs_fir_coefficient = + (WORD32)floor(0.5f - log10(fabs(pstr_unique_td_filter_element->fir_coefficient[idx])) / + (0.05f * 0.0625f)); + + if (bs_fir_coefficient > 1023) { + bs_fir_coefficient = 1023; + } + if (bs_fir_coefficient < 0) { + bs_fir_coefficient = 0; + } + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bs_fir_coefficient, 10); + } + } else { + bs_real_zero_radius_one_count = pstr_unique_td_filter_element->real_zero_radius_one_count / 2; + if ((pstr_unique_td_filter_element->real_zero_radius_one_count == + 2 * bs_real_zero_radius_one_count) && + (bs_real_zero_radius_one_count < 8)) { + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bs_real_zero_radius_one_count, 3); + } else { + return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG; + } + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_unique_td_filter_element->real_zero_count, 6); + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_unique_td_filter_element->generic_zero_count, 6); + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_unique_td_filter_element->real_pole_count, 4); + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_unique_td_filter_element->complex_pole_count, 4); + + for (idx = 0; idx < pstr_unique_td_filter_element->real_zero_radius_one_count; idx++) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, (UWORD32)pstr_unique_td_filter_element->zero_sign[idx], 1); + } + + for (idx = 0; idx < pstr_unique_td_filter_element->real_zero_count; idx++) { + err_code = impd_drc_encode_radius( + (FLOAT32)fabs(pstr_unique_td_filter_element->real_zero_radius[idx]), &code); + + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 7); + + if (pstr_unique_td_filter_element->real_zero_radius[idx] >= 0.0f) { + sign = 0; + } else { + sign = 1; + } + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, sign, 1); + } + + for (idx = 0; idx < pstr_unique_td_filter_element->generic_zero_count; idx++) { + err_code = + impd_drc_encode_radius(pstr_unique_td_filter_element->generic_zero_radius[idx], &code); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 7); + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, + impd_drc_encode_angle(pstr_unique_td_filter_element->generic_zero_angle[idx]), 7); + } + + for (idx = 0; idx < pstr_unique_td_filter_element->real_pole_count; idx++) { + err_code = impd_drc_encode_radius( + (FLOAT32)fabs(pstr_unique_td_filter_element->real_pole_radius[idx]), &code); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 7); + + if (pstr_unique_td_filter_element->real_pole_radius[idx] >= 0.0f) { + sign = 0; + } else { + sign = 1; + } + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, sign, 1); + } + + for (idx = 0; idx < pstr_unique_td_filter_element->complex_pole_count; idx++) { + err_code = + impd_drc_encode_radius(pstr_unique_td_filter_element->complex_pole_radius[idx], &code); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 7); + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, + impd_drc_encode_angle(pstr_unique_td_filter_element->complex_pole_angle[idx]), 7); + } + } + + *ptr_bit_cnt += bit_cnt_local; + + return err_code; +} + +static VOID impd_drc_encode_eq_slope(FLOAT32 eq_slope, WORD32 *size, WORD32 *code) { + LOOPIDX idx; + + if (fabs(eq_slope) >= 0.5f) { + *size = 5; + if (eq_slope > 32.0f) { + *code = 15; + } else if (eq_slope <= -32.0f) { + *code = 0; + } else { + idx = 1; + while (eq_slope > impd_drc_eq_slope_table[idx]) { + idx++; + } + if (eq_slope < 0.5f * (impd_drc_eq_slope_table[idx - 1] + impd_drc_eq_slope_table[idx])) { + idx--; + } + *code = idx; + } + } else { + *size = 1; + *code = 1; + } +} + +static VOID impd_drc_encode_eq_gain_initial(FLOAT32 eq_gain_initial, WORD32 *prefix_code, + WORD32 *size, WORD32 *code) { + if ((eq_gain_initial > -8.5f) && (eq_gain_initial < 7.75f)) { + *size = 5; + *prefix_code = 0; + *code = (WORD32)floor(0.5f + 2.0f * (MAX(-8.0f, eq_gain_initial) + 8.0f)); + } else if (eq_gain_initial < 0.0f) { + if (eq_gain_initial > -17.0f) { + *size = 4; + *prefix_code = 1; + *code = (WORD32)floor(0.5f + MAX(-16.0f, eq_gain_initial) + 16.0f); + } else if (eq_gain_initial > -34.0f) { + *size = 4; + *prefix_code = 2; + *code = (WORD32)floor(0.5f + 0.5f * (MAX(-32.0f, eq_gain_initial) + 32.0f)); + } else { + *size = 3; + *prefix_code = 3; + *code = (WORD32)floor(0.5f + 0.25f * (MAX(-64.0f, eq_gain_initial) + 64.0f)); + } + } else { + if (eq_gain_initial >= 15.5f) { + *size = 4; + *prefix_code = 2; + *code = (WORD32)floor(0.5f + 0.5f * MIN(30.0f, eq_gain_initial)); + } else { + *size = 4; + *prefix_code = 1; + *code = (WORD32)floor(0.5f + eq_gain_initial); + } + } +} + +static VOID impd_drc_encode_eq_gain_delta(FLOAT32 eq_gain_delta, WORD32 *code) { + LOOPIDX idx; + + if (eq_gain_delta >= 32.0f) { + *code = 31; + } else if (eq_gain_delta <= -22.0f) { + *code = 0; + } else { + idx = 1; + while (eq_gain_delta > impd_drc_eq_gain_delta_table[idx]) { + idx++; + } + if (eq_gain_delta < + 0.5f * (impd_drc_eq_gain_delta_table[idx - 1] + impd_drc_eq_gain_delta_table[idx])) { + idx--; + } + *code = idx; + } +} + +static VOID impd_drc_write_eq_subband_gain_spline( + ia_bit_buf_struct *it_bit_buf, + ia_drc_eq_subband_gain_spline_struct *pstr_eq_subband_gain_spline, WORD32 *ptr_bit_cnt) { + LOOPIDX idx; + WORD32 size, code, prefix_code; + WORD32 bit_cnt_local = 0; + WORD32 bs_eq_node_count = pstr_eq_subband_gain_spline->n_eq_nodes - 2; + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bs_eq_node_count, 5); + + for (idx = 0; idx < pstr_eq_subband_gain_spline->n_eq_nodes; idx++) { + impd_drc_encode_eq_slope(pstr_eq_subband_gain_spline->eq_slope[idx], &size, &code); + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, (UWORD8)size); + } + + for (idx = 1; idx < pstr_eq_subband_gain_spline->n_eq_nodes; idx++) { + code = MIN(15, pstr_eq_subband_gain_spline->eq_freq_delta[idx] - 1); + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 4); + } + + impd_drc_encode_eq_gain_initial(pstr_eq_subband_gain_spline->eq_gain_initial, &prefix_code, + &size, &code); + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, prefix_code, 2); + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, (UWORD8)size); + + for (idx = 1; idx < pstr_eq_subband_gain_spline->n_eq_nodes; idx++) { + impd_drc_encode_eq_gain_delta(pstr_eq_subband_gain_spline->eq_gain_delta[idx], &code); + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 5); + } + + *ptr_bit_cnt += bit_cnt_local; +} + +static VOID impd_drc_write_eq_subband_gain_vector( + ia_bit_buf_struct *it_bit_buf, WORD32 eq_subband_gain_count, + ia_drc_eq_subband_gain_vector_struct *pstr_eq_subband_gain_vector, WORD32 *ptr_bit_cnt) { + LOOPIDX idx = 0; + WORD32 sign; + WORD32 bs_eq_subband_gain; + WORD32 bit_cnt_local = 0; + + for (idx = 0; idx < eq_subband_gain_count; idx++) { + bs_eq_subband_gain = + (WORD32)floor(0.5f + fabs(pstr_eq_subband_gain_vector->eq_subband_gain[idx] * 8.0f)); + + if (pstr_eq_subband_gain_vector->eq_subband_gain[idx] >= 0.0f) { + sign = 0; + } else { + sign = 1; + } + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, sign, 1); + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bs_eq_subband_gain, 8); + } + + *ptr_bit_cnt += bit_cnt_local; +} + +static IA_ERRORCODE impd_drc_write_eq_coefficients( + ia_bit_buf_struct *it_bit_buf, ia_drc_eq_coefficients_struct *pstr_eq_coefficients, + WORD32 *ptr_bit_cnt) { + IA_ERRORCODE err_code = IA_NO_ERROR; + LOOPIDX idx; + WORD32 bs_eq_gain_count; + WORD32 mu = 0, nu = 0; + WORD32 bit_cnt_local = 0; + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_eq_coefficients->eq_delay_max_present, 1); + if (pstr_eq_coefficients->eq_delay_max_present == 1) { + for (nu = 0; nu < 8; nu++) { + mu = pstr_eq_coefficients->eq_delay_max / (16 << nu); + if (mu * (16 << nu) < pstr_eq_coefficients->eq_delay_max) { + mu++; + } + if (mu < 32) { + break; + } + } + if (nu == 8) { + mu = 31; + nu = 7; + } + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, mu, 5); + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, nu, 3); + } + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_eq_coefficients->unique_filter_block_count, 6); + for (idx = 0; idx < pstr_eq_coefficients->unique_filter_block_count; idx++) { + impd_drc_write_filter_block(it_bit_buf, &(pstr_eq_coefficients->str_filter_block[idx]), + &bit_cnt_local); + } + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_eq_coefficients->unique_td_filter_element_count, 6); + for (idx = 0; idx < pstr_eq_coefficients->unique_td_filter_element_count; idx++) { + err_code = impd_drc_write_unique_td_filter_element( + it_bit_buf, &(pstr_eq_coefficients->str_unique_td_filter_element[idx]), &bit_cnt_local); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + } + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_eq_coefficients->unique_eq_subband_gains_count, 6); + if (pstr_eq_coefficients->unique_eq_subband_gains_count > 0) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_eq_coefficients->eq_subband_gain_representation, 1); + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_eq_coefficients->eq_subband_gain_format, 4); + + switch (pstr_eq_coefficients->eq_subband_gain_format) { + case GAINFORMAT_QMFHYBRID135: + pstr_eq_coefficients->eq_subband_gain_count = 135; + break; + case GAINFORMAT_QMF128: + pstr_eq_coefficients->eq_subband_gain_count = 128; + break; + case GAINFORMAT_QMFHYBRID71: + pstr_eq_coefficients->eq_subband_gain_count = 71; + break; + case GAINFORMAT_QMF64: + pstr_eq_coefficients->eq_subband_gain_count = 64; + break; + case GAINFORMAT_QMFHYBRID39: + pstr_eq_coefficients->eq_subband_gain_count = 39; + break; + case GAINFORMAT_QMF32: + pstr_eq_coefficients->eq_subband_gain_count = 32; + break; + case GAINFORMAT_UNIFORM: + default: + bs_eq_gain_count = pstr_eq_coefficients->eq_subband_gain_count - 1; + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bs_eq_gain_count, 8); + break; + } + + for (idx = 0; idx < pstr_eq_coefficients->unique_eq_subband_gains_count; idx++) { + if (pstr_eq_coefficients->eq_subband_gain_representation != 1) { + impd_drc_write_eq_subband_gain_vector( + it_bit_buf, pstr_eq_coefficients->eq_subband_gain_count, + &(pstr_eq_coefficients->str_eq_subband_gain_vector[idx]), &bit_cnt_local); + } else { + impd_drc_write_eq_subband_gain_spline( + it_bit_buf, &(pstr_eq_coefficients->str_eq_subband_gain_spline[idx]), &bit_cnt_local); + } + } + } + + *ptr_bit_cnt += bit_cnt_local; + + return err_code; +} + +static VOID impd_drc_write_filter_block_refs( + ia_bit_buf_struct *it_bit_buf, ia_drc_filter_block_refs_struct *pstr_filter_block_refs, + WORD32 *ptr_bit_cnt) { + LOOPIDX idx; + WORD32 bit_cnt_local = 0; + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_filter_block_refs->filter_block_count, 4); + for (idx = 0; idx < pstr_filter_block_refs->filter_block_count; idx++) { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_filter_block_refs->filter_block_index[idx], 7); + } + + *ptr_bit_cnt += bit_cnt_local; +} + +static VOID impd_drc_write_td_filter_cascade( + ia_bit_buf_struct *it_bit_buf, const WORD32 eq_channel_group_count, + ia_drc_td_filter_cascade_struct *pstr_td_filter_cascade, WORD32 *ptr_bit_cnt) { + LOOPIDX i, j; + WORD32 bs_eq_cascade_gain; + WORD32 bit_cnt_local = 0; + + for (i = 0; i < eq_channel_group_count; i++) { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_td_filter_cascade->eq_cascade_gain_present[i], 1); + if (pstr_td_filter_cascade->eq_cascade_gain_present[i] == 1) { + bs_eq_cascade_gain = + (WORD32)floor(0.5f + 8.0f * (pstr_td_filter_cascade->eq_cascade_gain[i] + 96.0f)); + bs_eq_cascade_gain = MAX(0, bs_eq_cascade_gain); + bs_eq_cascade_gain = MIN(1023, bs_eq_cascade_gain); + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bs_eq_cascade_gain, 10); + } + impd_drc_write_filter_block_refs( + it_bit_buf, &(pstr_td_filter_cascade->str_filter_block_refs[i]), &bit_cnt_local); + } + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_td_filter_cascade->eq_phase_alignment_present, 1); + if (pstr_td_filter_cascade->eq_phase_alignment_present == 1) { + for (i = 0; i < eq_channel_group_count; i++) { + for (j = i + 1; j < eq_channel_group_count; j++) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_td_filter_cascade->eq_phase_alignment[i][j], 1); + } + } + } + + *ptr_bit_cnt += bit_cnt_local; +} + +static IA_ERRORCODE impd_drc_write_eq_instructions( + ia_bit_buf_struct *it_bit_buf, ia_drc_uni_drc_config_ext_struct *pstr_uni_drc_config_ext, + ia_drc_gain_enc_struct *pstr_gain_enc, ia_drc_eq_instructions_struct *pstr_eq_instructions, + WORD32 *ptr_bit_cnt, VOID *ptr_scratch, WORD32 *scratch_used) { + IA_ERRORCODE err_code = IA_NO_ERROR; + LOOPIDX idx; + WORD32 bs_eq_transition_duration; + WORD32 bit_cnt_local = 0; + FLOAT32 temp; + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->eq_set_id, 6); + + err_code = impd_drc_get_eq_complexity_level(pstr_uni_drc_config_ext, pstr_gain_enc, + pstr_eq_instructions, ptr_scratch, scratch_used); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->eq_set_complexity_level, 4); + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->downmix_id_present, 1); + if (pstr_eq_instructions->downmix_id_present == 1) { + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->downmix_id, 7); + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->eq_apply_to_downmix, 1); + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->additional_downmix_id_present, 1); + if (pstr_eq_instructions->additional_downmix_id_present == 1) { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->additional_downmix_id_count, 7); + for (idx = 0; idx < pstr_eq_instructions->additional_downmix_id_count; idx++) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_eq_instructions->additional_downmix_id[idx], 7); + } + } + } + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->drc_set_id, 6); + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->additional_drc_set_id_present, 1); + if (pstr_eq_instructions->additional_drc_set_id_present == 1) { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->additional_drc_set_id_count, 6); + for (idx = 0; idx < pstr_eq_instructions->additional_drc_set_id_count; idx++) { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->additional_drc_set_id[idx], 6); + } + } + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->eq_set_purpose, 16); + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->depends_on_eq_set_present, 1); + if (pstr_eq_instructions->depends_on_eq_set_present != 1) { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->no_independent_eq_use, 1); + } else { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->depends_on_eq_set, 6); + } + + for (idx = 0; idx < pstr_eq_instructions->eq_channel_count; idx++) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_eq_instructions->eq_channel_group_for_channel[idx], 7); + } + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->td_filter_cascade_present, 1); + if (pstr_eq_instructions->td_filter_cascade_present == 1) { + impd_drc_write_td_filter_cascade(it_bit_buf, pstr_eq_instructions->eq_channel_group_count, + &(pstr_eq_instructions->str_td_filter_cascade), + &bit_cnt_local); + } + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->subband_gains_present, 1); + if (pstr_eq_instructions->subband_gains_present == 1) { + for (idx = 0; idx < pstr_eq_instructions->eq_channel_group_count; idx++) { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->subband_gains_index[idx], 6); + } + } + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->eq_transition_duration_present, 1); + if (pstr_eq_instructions->eq_transition_duration_present == 1) { + temp = MAX(0.004f, pstr_eq_instructions->eq_transition_duration); + temp = MIN(0.861f, temp); + bs_eq_transition_duration = + (WORD32)floor(0.5f + 4.0f * (log10(1000.0f * temp) / log10(2.0f) - 2.0f)); + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bs_eq_transition_duration, 5); + } + + *ptr_bit_cnt += bit_cnt_local; + + return err_code; +} + +static IA_ERRORCODE impd_drc_write_uni_drc_config_extn( + ia_drc_enc_state *pstr_drc_state, ia_drc_gain_enc_struct *pstr_gain_enc, + ia_drc_uni_drc_config_struct *pstr_uni_drc_config, + ia_drc_uni_drc_config_ext_struct *pstr_uni_drc_config_ext, WORD32 *ptr_bit_cnt) { + IA_ERRORCODE err_code = IA_NO_ERROR; + LOOPIDX idx; + WORD32 version; + WORD32 counter = 0; + WORD32 ext_size_bits = 0, bit_size_len = 0, bit_size = 0; + WORD32 bit_cnt_local = 0, bit_cnt_local_ext = 0; + WORD32 *scratch_used = &pstr_drc_state->drc_scratch_used; + VOID *ptr_scratch = &pstr_drc_state->drc_scratch_mem; + ia_bit_buf_struct *it_bit_buf = &pstr_drc_state->str_bit_buf_cfg; + ia_bit_buf_struct *ptr_bit_buf_ext = &pstr_drc_state->str_bit_buf_cfg_ext; + + iusace_reset_bit_buffer(ptr_bit_buf_ext); + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_uni_drc_config_ext->uni_drc_config_ext_type[counter], 4); + while (counter < 2 && + pstr_uni_drc_config_ext->uni_drc_config_ext_type[counter] != UNIDRC_CONF_EXT_TERM) { + switch (pstr_uni_drc_config_ext->uni_drc_config_ext_type[counter]) { + case UNIDRC_CONF_EXT_PARAM_DRC: { + err_code = impd_drc_write_drc_coeff_parametric_drc( + ptr_bit_buf_ext, pstr_uni_drc_config, + &(pstr_uni_drc_config_ext->str_drc_coeff_parametric_drc), &bit_cnt_local_ext); + + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + + bit_cnt_local_ext += iusace_write_bits_buf( + ptr_bit_buf_ext, pstr_uni_drc_config_ext->parametric_drc_instructions_count, 4); + for (idx = 0; idx < pstr_uni_drc_config_ext->parametric_drc_instructions_count; idx++) { + err_code = impd_drc_write_parametric_drc_instructions( + ptr_bit_buf_ext, + pstr_uni_drc_config_ext->str_drc_coeff_parametric_drc.parametric_drc_frame_size, + &(pstr_uni_drc_config_ext->str_parametric_drc_instructions[idx]), + &bit_cnt_local_ext); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + } + } break; + case UNIDRC_CONF_EXT_V1: { + version = 1; + bit_cnt_local_ext += iusace_write_bits_buf( + ptr_bit_buf_ext, pstr_uni_drc_config_ext->downmix_instructions_v1_present, 1); + if (pstr_uni_drc_config_ext->downmix_instructions_v1_present == 1) { + bit_cnt_local_ext += iusace_write_bits_buf( + ptr_bit_buf_ext, pstr_uni_drc_config_ext->downmix_instructions_v1_count, 7); + for (idx = 0; idx < pstr_uni_drc_config_ext->downmix_instructions_v1_count; idx++) { + impd_drc_write_downmix_instructions( + ptr_bit_buf_ext, version, pstr_gain_enc, + &(pstr_uni_drc_config_ext->str_downmix_instructions_v1[idx]), &bit_cnt_local_ext); + } + } + + bit_cnt_local_ext += iusace_write_bits_buf( + ptr_bit_buf_ext, + pstr_uni_drc_config_ext->drc_coeffs_and_instructions_uni_drc_v1_present, 1); + if (pstr_uni_drc_config_ext->drc_coeffs_and_instructions_uni_drc_v1_present == 1) { + bit_cnt_local_ext += iusace_write_bits_buf( + ptr_bit_buf_ext, pstr_uni_drc_config_ext->drc_coefficients_uni_drc_v1_count, 3); + for (idx = 0; idx < pstr_uni_drc_config_ext->drc_coefficients_uni_drc_v1_count; idx++) { + impd_drc_write_drc_coeff_uni_drc( + ptr_bit_buf_ext, version, + &(pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[idx]), + &bit_cnt_local_ext); + } + + bit_cnt_local_ext += iusace_write_bits_buf( + ptr_bit_buf_ext, pstr_uni_drc_config_ext->drc_instructions_uni_drc_v1_count, 6); + for (idx = 0; idx < pstr_uni_drc_config_ext->drc_instructions_uni_drc_v1_count; idx++) { + err_code = impd_drc_write_drc_instruct_uni_drc( + ptr_bit_buf_ext, version, pstr_uni_drc_config, pstr_gain_enc, + &(pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[idx]), ptr_scratch, + &bit_cnt_local_ext); + if (err_code & IA_FATAL_ERROR) { + return (err_code); + } + } + } + + bit_cnt_local_ext += iusace_write_bits_buf( + ptr_bit_buf_ext, pstr_uni_drc_config_ext->loud_eq_instructions_present, 1); + if (pstr_uni_drc_config_ext->loud_eq_instructions_present == 1) { + bit_cnt_local_ext += iusace_write_bits_buf( + ptr_bit_buf_ext, pstr_uni_drc_config_ext->loud_eq_instructions_count, 4); + for (idx = 0; idx < pstr_uni_drc_config_ext->loud_eq_instructions_count; idx++) { + impd_drc_write_loud_eq_instructions( + ptr_bit_buf_ext, &(pstr_uni_drc_config_ext->str_loud_eq_instructions[idx]), + &bit_cnt_local_ext); + } + } + + bit_cnt_local_ext += + iusace_write_bits_buf(ptr_bit_buf_ext, pstr_uni_drc_config_ext->eq_present, 1); + if (pstr_uni_drc_config_ext->eq_present == 1) { + err_code = impd_drc_write_eq_coefficients( + ptr_bit_buf_ext, &(pstr_uni_drc_config_ext->str_eq_coefficients), + &bit_cnt_local_ext); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + + bit_cnt_local_ext += iusace_write_bits_buf( + ptr_bit_buf_ext, pstr_uni_drc_config_ext->eq_instructions_count, 4); + for (idx = 0; idx < pstr_uni_drc_config_ext->eq_instructions_count; idx++) { + err_code = impd_drc_write_eq_instructions( + ptr_bit_buf_ext, pstr_uni_drc_config_ext, pstr_gain_enc, + &(pstr_uni_drc_config_ext->str_eq_instructions[idx]), &bit_cnt_local_ext, + ptr_scratch, scratch_used); + if (err_code & IA_FATAL_ERROR) { + return (err_code); + } + } + } + } break; + default: + break; + } + + pstr_uni_drc_config_ext->ext_bit_size[counter] = bit_cnt_local_ext; + bit_size = pstr_uni_drc_config_ext->ext_bit_size[counter] - 1; + ext_size_bits = (WORD32)(log((FLOAT32)bit_size) / log(2.f)) + 1; + bit_size_len = ext_size_bits - 4; + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bit_size_len, 4); + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bit_size, (UWORD8)ext_size_bits); + + switch (pstr_uni_drc_config_ext->uni_drc_config_ext_type[counter]) { + case UNIDRC_CONF_EXT_PARAM_DRC: { + err_code = impd_drc_write_drc_coeff_parametric_drc( + it_bit_buf, pstr_uni_drc_config, + &(pstr_uni_drc_config_ext->str_drc_coeff_parametric_drc), &bit_cnt_local); + + if (err_code & IA_FATAL_ERROR) { + return (err_code); + } + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_uni_drc_config_ext->parametric_drc_instructions_count, 4); + for (idx = 0; idx < pstr_uni_drc_config_ext->parametric_drc_instructions_count; idx++) { + err_code = impd_drc_write_parametric_drc_instructions( + it_bit_buf, + pstr_uni_drc_config_ext->str_drc_coeff_parametric_drc.parametric_drc_frame_size, + &(pstr_uni_drc_config_ext->str_parametric_drc_instructions[idx]), &bit_cnt_local); + if (err_code & IA_FATAL_ERROR) { + return (err_code); + } + } + } break; + case UNIDRC_CONF_EXT_V1: { + version = 1; + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_uni_drc_config_ext->downmix_instructions_v1_present, 1); + if (pstr_uni_drc_config_ext->downmix_instructions_v1_present == 1) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_uni_drc_config_ext->downmix_instructions_v1_count, 7); + for (idx = 0; idx < pstr_uni_drc_config_ext->downmix_instructions_v1_count; idx++) { + impd_drc_write_downmix_instructions( + it_bit_buf, version, pstr_gain_enc, + &(pstr_uni_drc_config_ext->str_downmix_instructions_v1[idx]), &bit_cnt_local); + } + } + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_uni_drc_config_ext->drc_coeffs_and_instructions_uni_drc_v1_present, + 1); + if (pstr_uni_drc_config_ext->drc_coeffs_and_instructions_uni_drc_v1_present == 1) { + version = 1; + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_uni_drc_config_ext->drc_coefficients_uni_drc_v1_count, 3); + for (idx = 0; idx < pstr_uni_drc_config_ext->drc_coefficients_uni_drc_v1_count; idx++) { + impd_drc_write_drc_coeff_uni_drc( + it_bit_buf, version, + &(pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[idx]), &bit_cnt_local); + } + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_uni_drc_config_ext->drc_instructions_uni_drc_v1_count, 6); + for (idx = 0; idx < pstr_uni_drc_config_ext->drc_instructions_uni_drc_v1_count; idx++) { + err_code = impd_drc_write_drc_instruct_uni_drc( + it_bit_buf, version, pstr_uni_drc_config, pstr_gain_enc, + &(pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[idx]), ptr_scratch, + &bit_cnt_local); + if (err_code & IA_FATAL_ERROR) { + return (err_code); + } + } + } + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_uni_drc_config_ext->loud_eq_instructions_present, 1); + if (pstr_uni_drc_config_ext->loud_eq_instructions_present == 1) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_uni_drc_config_ext->loud_eq_instructions_count, 4); + for (idx = 0; idx < pstr_uni_drc_config_ext->loud_eq_instructions_count; idx++) { + impd_drc_write_loud_eq_instructions( + it_bit_buf, &(pstr_uni_drc_config_ext->str_loud_eq_instructions[idx]), + &bit_cnt_local); + } + } + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_uni_drc_config_ext->eq_present, 1); + if (pstr_uni_drc_config_ext->eq_present == 1) { + err_code = impd_drc_write_eq_coefficients( + it_bit_buf, &(pstr_uni_drc_config_ext->str_eq_coefficients), &bit_cnt_local); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_uni_drc_config_ext->eq_instructions_count, 4); + for (idx = 0; idx < pstr_uni_drc_config_ext->eq_instructions_count; idx++) { + err_code = impd_drc_write_eq_instructions( + it_bit_buf, pstr_uni_drc_config_ext, pstr_gain_enc, + &(pstr_uni_drc_config_ext->str_eq_instructions[idx]), &bit_cnt_local, ptr_scratch, + scratch_used); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + } + } + } break; + default: + for (idx = 0; idx < pstr_uni_drc_config_ext->ext_bit_size[counter]; idx++) { + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, 0, 1); + } + break; + } + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_uni_drc_config_ext->uni_drc_config_ext_type[counter], 4); + + counter++; + } + + *ptr_bit_cnt += bit_cnt_local; + + return err_code; +} + +IA_ERRORCODE impd_drc_write_loudness_info_set_extension( + ia_drc_enc_state *pstr_drc_state, ia_bit_buf_struct *it_bit_buf, + ia_drc_loudness_info_set_extension_struct *pstr_loudness_info_set_extension, + WORD32 *ptr_bit_cnt) { + IA_ERRORCODE err_code = IA_NO_ERROR; + LOOPIDX idx; + WORD32 counter = 0, version = 1; + WORD32 ext_size_bits = 0, bit_size_len = 0, bit_size = 0; + WORD32 bit_cnt_local = 0; + WORD32 bit_cnt_local_tmp = 0; + ia_drc_loudness_info_set_ext_eq_struct *pstr_loudness_info_set_ext_eq = + &pstr_loudness_info_set_extension->str_loudness_info_set_ext_eq; + ia_bit_buf_struct *ptr_bit_buf_tmp = &pstr_drc_state->str_bit_buf_cfg_tmp; + + iusace_reset_bit_buffer(ptr_bit_buf_tmp); + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_loudness_info_set_extension->loudness_info_set_ext_type[counter], 4); + while ((counter < 2) && + (pstr_loudness_info_set_extension->loudness_info_set_ext_type[counter] != + UNIDRC_LOUD_EXT_TERM)) { + switch (pstr_loudness_info_set_extension->loudness_info_set_ext_type[counter]) { + case UNIDRC_LOUD_EXT_EQ: { + bit_cnt_local_tmp += iusace_write_bits_buf( + ptr_bit_buf_tmp, pstr_loudness_info_set_ext_eq->loudness_info_v1_album_count, 6); + + bit_cnt_local_tmp += iusace_write_bits_buf( + ptr_bit_buf_tmp, pstr_loudness_info_set_ext_eq->loudness_info_v1_count, 6); + for (idx = 0; idx < pstr_loudness_info_set_ext_eq->loudness_info_v1_album_count; idx++) { + err_code = impd_drc_write_loudness_info( + ptr_bit_buf_tmp, version, + &(pstr_loudness_info_set_ext_eq->str_loudness_info_v1_album[idx]), + &bit_cnt_local_tmp); + if (err_code) { + return err_code; + } + } + for (idx = 0; idx < pstr_loudness_info_set_ext_eq->loudness_info_v1_count; idx++) { + err_code = impd_drc_write_loudness_info( + ptr_bit_buf_tmp, version, + &(pstr_loudness_info_set_ext_eq->str_loudness_info_v1[idx]), &bit_cnt_local_tmp); + if (err_code) { + return (err_code); + } + } + } break; + default: + break; + } + pstr_loudness_info_set_extension->ext_bit_size[counter] = bit_cnt_local_tmp; + bit_size = pstr_loudness_info_set_extension->ext_bit_size[counter] - 1; + ext_size_bits = (WORD32)(log((FLOAT32)bit_size) / log(2.f)) + 1; + bit_size_len = ext_size_bits - 4; + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bit_size_len, 4); + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bit_size, (UWORD8)ext_size_bits); + + switch (pstr_loudness_info_set_extension->loudness_info_set_ext_type[counter]) { + case UNIDRC_LOUD_EXT_EQ: { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_loudness_info_set_ext_eq->loudness_info_v1_album_count, 6); + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_loudness_info_set_ext_eq->loudness_info_v1_count, 6); + for (idx = 0; idx < pstr_loudness_info_set_ext_eq->loudness_info_v1_album_count; idx++) { + err_code = impd_drc_write_loudness_info( + it_bit_buf, version, + &(pstr_loudness_info_set_ext_eq->str_loudness_info_v1_album[idx]), &bit_cnt_local); + if (err_code) { + return err_code; + } + } + for (idx = 0; idx < pstr_loudness_info_set_ext_eq->loudness_info_v1_count; idx++) { + err_code = impd_drc_write_loudness_info( + it_bit_buf, version, &(pstr_loudness_info_set_ext_eq->str_loudness_info_v1[idx]), + &bit_cnt_local); + if (err_code) { + return (err_code); + } + } + } break; + default: + for (idx = 0; idx < pstr_loudness_info_set_extension->ext_bit_size[counter]; idx++) { + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, 0, 1); + } + break; + } + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_loudness_info_set_extension->loudness_info_set_ext_type[counter], 4); + + counter++; + } + + *ptr_bit_cnt += bit_cnt_local; + + return IA_NO_ERROR; +} + +IA_ERRORCODE impd_drc_write_loudness_info_set(ia_drc_enc_state *pstr_drc_state, + ia_bit_buf_struct *it_bit_buf, + WORD32 *ptr_bit_cnt) { + IA_ERRORCODE err_code = IA_NO_ERROR; + LOOPIDX idx; + WORD32 version = 0; + WORD32 bit_cnt_local = 0; + ia_drc_gain_enc_struct *pstr_gain_enc = &pstr_drc_state->str_gain_enc; + ia_drc_loudness_info_set_struct *pstr_loudness_info_set = + &(pstr_gain_enc->str_loudness_info_set); + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_loudness_info_set->loudness_info_album_count, 6); + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_loudness_info_set->loudness_info_count, 6); + + for (idx = 0; idx < pstr_loudness_info_set->loudness_info_album_count; idx++) { + err_code = impd_drc_write_loudness_info(it_bit_buf, version, + &pstr_loudness_info_set->str_loudness_info_album[idx], + &bit_cnt_local); + if (err_code) { + return err_code; + } + } + + for (idx = 0; idx < pstr_loudness_info_set->loudness_info_count; idx++) { + err_code = impd_drc_write_loudness_info( + it_bit_buf, version, &pstr_loudness_info_set->str_loudness_info[idx], &bit_cnt_local); + if (err_code) { + return err_code; + } + } + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_loudness_info_set->loudness_info_set_ext_present, 1); + if (pstr_loudness_info_set->loudness_info_set_ext_present) { + err_code = impd_drc_write_loudness_info_set_extension( + pstr_drc_state, it_bit_buf, &pstr_loudness_info_set->str_loudness_info_set_extension, + &bit_cnt_local); + if (err_code) { + return err_code; + } + } + + *ptr_bit_cnt += bit_cnt_local; + + return err_code; +} + +IA_ERRORCODE impd_drc_write_uni_drc_config(ia_drc_enc_state *pstr_drc_state, + WORD32 *ptr_bit_cnt) { + IA_ERRORCODE err_code = IA_NO_ERROR; + LOOPIDX idx; + WORD32 version = 0; + WORD32 bit_cnt_local = 0; + VOID *ptr_scratch = pstr_drc_state->drc_scratch_mem; + ia_bit_buf_struct *it_bit_buf = &pstr_drc_state->str_bit_buf_cfg; + ia_drc_gain_enc_struct *pstr_gain_enc = &pstr_drc_state->str_gain_enc; + ia_drc_uni_drc_config_struct *pstr_uni_drc_config = &(pstr_gain_enc->str_uni_drc_config); + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_uni_drc_config->sample_rate_present, 1); + + if (1 == pstr_uni_drc_config->sample_rate_present) { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, (pstr_uni_drc_config->sample_rate - 1000), 18); + } + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_uni_drc_config->downmix_instructions_count, 7); + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_uni_drc_config->drc_description_basic_present, 1); + + if (1 == pstr_uni_drc_config->drc_description_basic_present) { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_uni_drc_config->drc_coefficients_basic_count, 3); + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_uni_drc_config->drc_instructions_basic_count, 4); + } + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_uni_drc_config->drc_coefficients_uni_drc_count, 3); + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_uni_drc_config->drc_instructions_uni_drc_count, 6); + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_uni_drc_config->str_channel_layout.base_ch_count, 7); + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_uni_drc_config->str_channel_layout.layout_signaling_present, 1); + if (1 == pstr_uni_drc_config->str_channel_layout.layout_signaling_present) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_uni_drc_config->str_channel_layout.defined_layout, 8); + if (0 == pstr_uni_drc_config->str_channel_layout.defined_layout) { + for (idx = 0; idx < pstr_uni_drc_config->str_channel_layout.base_ch_count; idx++) { + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_uni_drc_config->str_channel_layout.speaker_position[idx], 7); + } + } + } + + for (idx = 0; idx < pstr_uni_drc_config->downmix_instructions_count; idx++) { + // downmixInstructions(); + } + + for (idx = 0; idx < pstr_uni_drc_config->drc_coefficients_basic_count; idx++) { + // drcCoefficientsBasic(); + } + + for (idx = 0; idx < pstr_uni_drc_config->drc_instructions_basic_count; idx++) { + // drcInstructionsBasics(); + } + + for (idx = 0; idx < pstr_uni_drc_config->drc_coefficients_uni_drc_count; idx++) { + impd_drc_write_drc_coeff_uni_drc(it_bit_buf, version, + &(pstr_uni_drc_config->str_drc_coefficients_uni_drc[idx]), + &bit_cnt_local); + } + + for (idx = 0; idx < pstr_uni_drc_config->drc_instructions_uni_drc_count; idx++) { + err_code = impd_drc_write_drc_instruct_uni_drc( + it_bit_buf, version, pstr_uni_drc_config, pstr_gain_enc, + &(pstr_uni_drc_config->str_drc_instructions_uni_drc[idx]), ptr_scratch, &bit_cnt_local); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + } + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_uni_drc_config->uni_drc_config_ext_present, 1); + if (pstr_uni_drc_config->uni_drc_config_ext_present) { + err_code = impd_drc_write_uni_drc_config_extn( + pstr_drc_state, pstr_gain_enc, pstr_uni_drc_config, + &(pstr_uni_drc_config->str_uni_drc_config_ext), &bit_cnt_local); + if (err_code & IA_FATAL_ERROR) { + return (err_code); + } + } + + // Loudness info set + if (pstr_uni_drc_config->loudness_info_set_present == 1) { + ia_bit_buf_struct *it_bit_buf_lis = &pstr_drc_state->str_bit_buf_cfg_ext; + WORD32 bit_cnt_lis = 0; + err_code = impd_drc_write_loudness_info_set(pstr_drc_state, it_bit_buf_lis, &bit_cnt_lis); + if (err_code & IA_FATAL_ERROR) { + return (err_code); + } + pstr_drc_state->drc_config_ext_data_size_bit = bit_cnt_lis; + } + + *ptr_bit_cnt += bit_cnt_local; + + return err_code; +} + +IA_ERRORCODE impd_drc_enc_initial_gain(const WORD32 gain_coding_profile, FLOAT32 gain_initial, + FLOAT32 *gain_initial_quant, WORD32 *code_size, + WORD32 *code) { + WORD32 sign, magnitude, bits, size; + + switch (gain_coding_profile) { + case GAIN_CODING_PROFILE_CONSTANT: { + bits = 0; + size = 0; + } break; + case GAIN_CODING_PROFILE_CLIPPING: { + if (gain_initial > -0.0625f) { + sign = 0; + *gain_initial_quant = 0.0f; + bits = sign; + size = 1; + } else { + sign = 1; + gain_initial = MAX(-1000.0f, gain_initial); + magnitude = (WORD32)(-1.0f + 0.5f - 8.0f * gain_initial); + magnitude = MIN(0xFF, magnitude); + *gain_initial_quant = -(magnitude + 1) * 0.125f; + bits = (sign << 8) + magnitude; + size = 9; + } + } break; + case GAIN_CODING_PROFILE_FADING: { + if (gain_initial > -0.0625f) { + sign = 0; + *gain_initial_quant = 0.0f; + bits = sign; + size = 1; + } else { + sign = 1; + gain_initial = MAX(-1000.0f, gain_initial); + magnitude = (WORD32)(-1.0f + 0.5f - 8.0f * gain_initial); + magnitude = MIN(0x3FF, magnitude); + *gain_initial_quant = -(magnitude + 1) * 0.125f; + bits = (sign << 10) + magnitude; + size = 11; + } + } break; + case GAIN_CODING_PROFILE_REGULAR: { + if (gain_initial < 0.0f) { + sign = 1; + gain_initial = MAX(-1000.0f, gain_initial); + magnitude = (WORD32)(0.5f - 8.0f * gain_initial); + magnitude = MIN(0xFF, magnitude); + *gain_initial_quant = -magnitude * 0.125f; + } else { + sign = 0; + gain_initial = MIN(1000.0f, gain_initial); + magnitude = (WORD32)(0.5f + 8.0f * gain_initial); + magnitude = MIN(0xFF, magnitude); + *gain_initial_quant = magnitude * 0.125f; + } + bits = (sign << 8) + magnitude; + size = 9; + } break; + default: + return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG; + } + + *code = bits; + *code_size = size; + + return IA_NO_ERROR; +} + +static VOID impd_drc_write_spline_nodes(ia_bit_buf_struct *it_bit_buf, + ia_drc_gain_enc_struct *pstr_gain_enc, + ia_drc_gain_set_params_struct *pstr_gain_set_params, + ia_drc_group_for_output_struct *pstr_drc_group_for_output, + WORD32 *ptr_bit_cnt) { + LOOPIDX idx; + WORD32 frame_end_flag; + WORD32 bit_cnt_local = 0; + + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_drc_group_for_output->coding_mode, 1); + if (pstr_drc_group_for_output->coding_mode != 0) { + for (idx = 0; idx < pstr_drc_group_for_output->n_gain_values - 1; idx++) { + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, 0, 1); + } + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, 1, 1); + + if (pstr_gain_set_params->gain_interpolation_type == GAIN_INTERPOLATION_TYPE_SPLINE) { + for (idx = 0; idx < pstr_drc_group_for_output->n_gain_values; idx++) { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_drc_group_for_output->slope_code[idx], + (UWORD8)pstr_drc_group_for_output->slope_code_size[idx]); + } + } + + if (pstr_gain_set_params->full_frame == 0 && pstr_drc_group_for_output->n_gain_values > 0) { + if (pstr_drc_group_for_output->ts_gain_quant[pstr_drc_group_for_output->n_gain_values - + 1] == (pstr_gain_enc->drc_frame_size - 1)) { + frame_end_flag = 1; + } else { + frame_end_flag = 0; + } + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, frame_end_flag, 1); + } else { + frame_end_flag = 1; + } + + for (idx = 0; idx < pstr_drc_group_for_output->n_gain_values; idx++) { + if (idx < (pstr_drc_group_for_output->n_gain_values - 1) || !frame_end_flag) { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_drc_group_for_output->time_delta_code[idx], + (UWORD8)pstr_drc_group_for_output->time_delta_code_size[idx]); + } + } + for (idx = 0; idx < pstr_drc_group_for_output->n_gain_values; idx++) { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_drc_group_for_output->gain_code[idx], + (UWORD8)pstr_drc_group_for_output->gain_code_length[idx]); + } + } else { + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_drc_group_for_output->gain_code[0], + (UWORD8)pstr_drc_group_for_output->gain_code_length[0]); + } + + *ptr_bit_cnt += bit_cnt_local; +} + +static VOID impd_drc_write_uni_drc_gain_extension( + ia_bit_buf_struct *it_bit_buf, ia_drc_uni_drc_gain_ext_struct *pstr_uni_drc_gain_ext, + WORD32 *ptr_bit_cnt) { + LOOPIDX idx; + WORD32 counter = 0; + WORD32 ext_size_bits, bit_size_len, bit_size; + WORD32 bit_cnt_local = 0; + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, pstr_uni_drc_gain_ext->uni_drc_gain_ext_type[counter], 4); + while (pstr_uni_drc_gain_ext->uni_drc_gain_ext_type[counter] != UNIDRC_GAIN_EXT_TERM) { + bit_size = pstr_uni_drc_gain_ext->ext_bit_size[counter] - 1; + ext_size_bits = (WORD32)(log((FLOAT32)bit_size) / log(2.f)) + 1; + bit_size_len = ext_size_bits - 4; + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bit_size_len, 3); + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bit_size, (UWORD8)ext_size_bits); + switch (pstr_uni_drc_gain_ext->uni_drc_gain_ext_type[counter]) { + default: + for (idx = 0; idx < pstr_uni_drc_gain_ext->ext_bit_size[counter]; idx++) { + bit_cnt_local += iusace_write_bits_buf(it_bit_buf, 0, 1); + } + } + counter++; + + bit_cnt_local += iusace_write_bits_buf( + it_bit_buf, pstr_uni_drc_gain_ext->uni_drc_gain_ext_type[counter], 4); + } + + *ptr_bit_cnt += bit_cnt_local; +} + +VOID impd_drc_write_uni_drc_gain(ia_drc_enc_state *pstr_drc_state, WORD32 *ptr_bit_cnt) { + LOOPIDX idx; + WORD32 bit_cnt_local = 0; + ia_bit_buf_struct *it_bit_buf = &pstr_drc_state->str_bit_buf_out; + ia_drc_gain_enc_struct *pstr_gain_enc = &pstr_drc_state->str_gain_enc; + ia_drc_group_for_output_struct *pstr_drc_group_for_output; + ia_drc_gain_set_params_struct *pstr_gain_set_params; + ia_drc_uni_drc_gain_ext_struct str_uni_drc_gain_extension = + pstr_drc_state->str_enc_gain_extension; + + for (idx = 0; idx < pstr_gain_enc->n_sequences; idx++) { + pstr_drc_group_for_output = + &(pstr_gain_enc->str_drc_gain_seq_buf[idx].str_drc_group_for_output); + pstr_gain_set_params = &(pstr_gain_enc->str_drc_gain_seq_buf[idx].str_gain_set_params); + + if (pstr_gain_set_params->gain_coding_profile < GAIN_CODING_PROFILE_CONSTANT) { + impd_drc_write_spline_nodes(it_bit_buf, pstr_gain_enc, pstr_gain_set_params, + pstr_drc_group_for_output, &bit_cnt_local); + } + } + + bit_cnt_local += + iusace_write_bits_buf(it_bit_buf, str_uni_drc_gain_extension.uni_drc_gain_ext_present, 1); + if (str_uni_drc_gain_extension.uni_drc_gain_ext_present) { + impd_drc_write_uni_drc_gain_extension(it_bit_buf, &str_uni_drc_gain_extension, + &bit_cnt_local); + } + + if (bit_cnt_local & 0x07) { + pstr_drc_state->bit_buf_base_out[bit_cnt_local >> 3] |= 0xFF >> (bit_cnt_local & 0x07); + + bit_cnt_local += 8 - (bit_cnt_local & 0x07); + } + + *ptr_bit_cnt += bit_cnt_local; +} diff --git a/encoder/ixheaace_sbr_hbe_fft_ifft_rom.h b/encoder/drc_src/impd_drc_mux.h similarity index 62% rename from encoder/ixheaace_sbr_hbe_fft_ifft_rom.h rename to encoder/drc_src/impd_drc_mux.h index fd1da67..6f5fc0a 100644 --- a/encoder/ixheaace_sbr_hbe_fft_ifft_rom.h +++ b/encoder/drc_src/impd_drc_mux.h @@ -19,16 +19,17 @@ */ #pragma once +#define MIN_DRC_GAIN_CODING_PROFILE0 (-31.875f) +#define MAX_DRC_GAIN_CODING_PROFILE0 (31.875f) -extern const FLOAT64 ixheaace_twid_tbl_fft[514]; -extern const WORD32 twiddle_tab_fft_32x32[514]; -extern const FLOAT64 ixheaace_twid_tbl_fft_ntwt3r[1155]; -extern const FLOAT64 ixheaace_twid_tbl_fft_ntwt3i[1155]; -extern const FLOAT32 ixheaace_twid_tbl_fft_224[372]; -extern const FLOAT32 ixheaace_twid_tbl_fft_288[380]; -extern const FLOAT32 ixheaace_twid_tbl_fft_336[564]; -extern const FLOAT32 ixheaace_twid_tbl_fft_168[276]; +#define MIN_DRC_GAIN_CODING_PROFILE1 (-128.0f) +#define MAX_DRC_GAIN_CODING_PROFILE1 (0.0f) -extern const FLOAT32 ixheaace_twiddle_tab_fft_float[514]; -extern const FLOAT32 ixheaace_twidle_tbl_48[64]; -extern const FLOAT32 ixheaace_twidle_tbl_24[32]; +#define MIN_DRC_GAIN_CODING_PROFILE2 (-32.0f) +#define MAX_DRC_GAIN_CODING_PROFILE2 (0.0f) + +#define INV_LOG10_2 (3.32192809488736f) /* 1.0 / log10(2.0) */ + +IA_ERRORCODE impd_drc_enc_initial_gain(const WORD32 gain_coding_profile, FLOAT32 gain_initial, + FLOAT32 *gain_initial_quant, WORD32 *code_size, + WORD32 *code); diff --git a/encoder/drc_src/impd_drc_struct_def.h b/encoder/drc_src/impd_drc_struct_def.h new file mode 100644 index 0000000..7081192 --- /dev/null +++ b/encoder/drc_src/impd_drc_struct_def.h @@ -0,0 +1,51 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +#define MAX_DRC_GAIN_BAND_COUNT (50) +#define MAX_DRC_FRAME_SIZE (4096) +#define DRC_OUT_BITBUFFER_SIZE (4096) + +typedef struct { + ia_drc_enc_params_struct str_enc_params; + ia_drc_uni_drc_config_struct str_uni_drc_config; + ia_drc_loudness_info_set_struct str_enc_loudness_info_set; + ia_drc_uni_drc_gain_ext_struct str_enc_gain_extension; + + ia_drc_gain_enc_struct str_gain_enc; + UWORD8 bit_buf_base_cfg[MAX_DRC_PAYLOAD_BYTES]; + ia_bit_buf_struct str_bit_buf_cfg; + WORD32 drc_config_data_size_bit; + UWORD8 bit_buf_base_cfg_ext[MAX_DRC_PAYLOAD_BYTES]; + ia_bit_buf_struct str_bit_buf_cfg_ext; + WORD32 drc_config_ext_data_size_bit; + UWORD8 bit_buf_base_cfg_tmp[MAX_DRC_PAYLOAD_BYTES]; + ia_bit_buf_struct str_bit_buf_cfg_tmp; + + UWORD8 drc_payload_data[MAX_DRC_PAYLOAD_BYTES]; + FLOAT32 gain_buffer[MAX_DRC_GAIN_BAND_COUNT][MAX_DRC_FRAME_SIZE]; + + UWORD8 bit_buf_base_out[DRC_OUT_BITBUFFER_SIZE]; + ia_bit_buf_struct str_bit_buf_out; + UWORD8 is_first_drc_process_complete; + + VOID *drc_scratch_mem; + WORD32 drc_scratch_used; +} ia_drc_enc_state; diff --git a/encoder/drc_src/impd_drc_tables.c b/encoder/drc_src/impd_drc_tables.c new file mode 100644 index 0000000..e214e0d --- /dev/null +++ b/encoder/drc_src/impd_drc_tables.c @@ -0,0 +1,214 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include "ixheaac_type_def.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" + +const FLOAT32 impd_drc_downmix_coeff[16] = {0.0f, -0.5f, -1.0f, -1.5f, -2.0f, -2.5f, + -3.0f, -3.5f, -4.0f, -4.5f, -5.0f, -5.5f, + -6.0f, -7.5f, -9.0f, -1000.0f}; + +const FLOAT32 impd_drc_downmix_coeff_lfe[16] = {10.0f, 6.0f, 4.5f, 3.0f, 1.5f, 0.0f, + -1.5f, -3.0f, -4.5f, -6.0f, -10.0f, -15.0f, + -20.0f, -30.0f, -40.0f, -1000.0f}; + +const FLOAT32 impd_drc_channel_weight[16] = {10.0f, 6.0f, 4.5f, 3.0f, 1.5f, 0.0f, + -1.5f, -3.0f, -4.5f, -6.0f, -10.0f, -15.0f, + -20.0f, -30.0f, -40.0f, -1000.0f}; + +const FLOAT32 impd_drc_downmix_coeff_v1[32] = { + 10.00f, 6.00f, 4.50f, 3.00f, 1.50f, 0.00f, -0.50f, -1.00f, + -1.50f, -2.00f, -2.50f, -3.00f, -3.50f, -4.00f, -4.50f, -5.00f, + -5.50f, -6.00f, -6.50f, -7.00f, -7.50f, -8.00f, -9.00f, -10.00f, + -11.00f, -12.00f, -15.00f, -20.00f, -25.00f, -30.00f, -40.00f, -100000.0f}; + +const FLOAT32 impd_drc_eq_slope_table[16] = {-32.0f, -24.0f, -18.0f, -12.0f, -7.0f, -4.0f, + -2.0f, -1.0f, 1.0f, 2.0f, 4.0f, 7.0f, + 12.0f, 18.0f, 24.0f, 32.0f}; + +const FLOAT32 impd_drc_eq_gain_delta_table[32] = { + -22.0f, -16.0f, -13.0f, -11.0f, -9.0f, -7.0f, -6.0f, -5.0f, -4.0f, -3.0f, -2.5f, + -2.0f, -1.5f, -1.0f, -0.5f, 0.0f, 0.5f, 1.0f, 1.5f, 2.0f, 2.5f, 3.0f, + 4.0f, 5.0f, 6.0f, 7.0f, 9.0f, 11.0f, 13.0f, 16.0f, 22.0f, 32.0f}; + +const FLOAT32 impd_drc_zero_pole_radius_table[128] = { + 0.00000000E+00f, 7.57409621E-11f, 7.47451079E-09f, 7.37623509E-08f, 3.37872933E-07f, + 1.05439995E-06f, 2.61370951E-06f, 5.55702854E-06f, 1.05878771E-05f, 1.85806475E-05f, + 3.05868707E-05f, 4.78395414E-05f, 7.17558214E-05f, 1.03938342E-04f, 1.46175269E-04f, + 2.00439375E-04f, 2.68886099E-04f, 3.53850890E-04f, 4.57845890E-04f, 5.83555840E-04f, + 7.33833469E-04f, 9.11694835E-04f, 1.12031354E-03f, 1.36301492E-03f, 1.64327072E-03f, + 1.96469179E-03f, 2.33102194E-03f, 2.74613220E-03f, 3.21401190E-03f, 3.73876374E-03f, + 4.32459544E-03f, 4.97581391E-03f, 5.69681637E-03f, 6.49208482E-03f, 7.36617809E-03f, + 8.32372531E-03f, 9.36941616E-03f, 1.05079999E-02f, 1.17442720E-02f, 1.30830696E-02f, + 1.45292655E-02f, 1.60877611E-02f, 1.77634824E-02f, 1.95613634E-02f, 2.14863531E-02f, + 2.35434026E-02f, 2.57374570E-02f, 2.80734543E-02f, 3.05563174E-02f, 3.31909470E-02f, + 3.59822176E-02f, 3.89349759E-02f, 4.20540236E-02f, 4.53441292E-02f, 4.88100089E-02f, + 5.24563305E-02f, 5.62877022E-02f, 6.03086725E-02f, 6.45237267E-02f, 6.89372867E-02f, + 7.35536888E-02f, 7.83772022E-02f, 8.34120139E-02f, 8.86622295E-02f, 9.41318572E-02f, + 9.98248383E-02f, 1.05744988E-01f, 1.11896060E-01f, 1.18281692E-01f, 1.24905407E-01f, + 1.31770656E-01f, 1.38880774E-01f, 1.46238968E-01f, 1.53848350E-01f, 1.61711931E-01f, + 1.69832602E-01f, 1.78213134E-01f, 1.86856180E-01f, 1.95764288E-01f, 2.04939872E-01f, + 2.14385241E-01f, 2.24102572E-01f, 2.34093949E-01f, 2.44361281E-01f, 2.54906416E-01f, + 2.65731007E-01f, 2.76836663E-01f, 2.88224846E-01f, 2.99896836E-01f, 3.11853856E-01f, + 3.24096978E-01f, 3.36627185E-01f, 3.49445283E-01f, 3.62551987E-01f, 3.75947863E-01f, + 3.89633417E-01f, 4.03608948E-01f, 4.17874694E-01f, 4.32430804E-01f, 4.47277188E-01f, + 4.62413728E-01f, 4.77840215E-01f, 4.93556231E-01f, 5.09561300E-01f, 5.25854886E-01f, + 5.42436182E-01f, 5.59304416E-01f, 5.76458573E-01f, 5.93897760E-01f, 6.11620665E-01f, + 6.29626155E-01f, 6.47912800E-01f, 6.66479111E-01f, 6.85323536E-01f, 7.04444408E-01f, + 7.23839939E-01f, 7.43508339E-01f, 7.63447523E-01f, 7.83655465E-01f, 8.04130018E-01f, + 8.24868977E-01f, 8.45869958E-01f, 8.67130578E-01f, 8.88648331E-01f, 9.10420537E-01f, + 9.32444632E-01f, 9.54717815E-01f, 9.77237225E-01f}; + +const FLOAT32 impd_drc_zero_pole_angle_table[128] = { + 0.00000000E+00f, 6.90533966E-04f, 7.31595252E-04f, 7.75098170E-04f, 8.21187906E-04f, + 8.70018279E-04f, 9.21752258E-04f, 9.76562500E-04f, 1.03463193E-03f, 1.09615434E-03f, + 1.16133507E-03f, 1.23039165E-03f, 1.30355455E-03f, 1.38106793E-03f, 1.46319050E-03f, + 1.55019634E-03f, 1.64237581E-03f, 1.74003656E-03f, 1.84350452E-03f, 1.95312500E-03f, + 2.06926386E-03f, 2.19230869E-03f, 2.32267015E-03f, 2.46078330E-03f, 2.60710909E-03f, + 2.76213586E-03f, 2.92638101E-03f, 3.10039268E-03f, 3.28475162E-03f, 3.48007312E-03f, + 3.68700903E-03f, 3.90625000E-03f, 4.13852771E-03f, 4.38461738E-03f, 4.64534029E-03f, + 4.92156660E-03f, 5.21421818E-03f, 5.52427173E-03f, 5.85276202E-03f, 6.20078536E-03f, + 6.56950324E-03f, 6.96014624E-03f, 7.37401807E-03f, 7.81250000E-03f, 8.27705542E-03f, + 8.76923475E-03f, 9.29068059E-03f, 9.84313320E-03f, 1.04284364E-02f, 1.10485435E-02f, + 1.17055240E-02f, 1.24015707E-02f, 1.31390065E-02f, 1.39202925E-02f, 1.47480361E-02f, + 1.56250000E-02f, 1.65541108E-02f, 1.75384695E-02f, 1.85813612E-02f, 1.96862664E-02f, + 2.08568727E-02f, 2.20970869E-02f, 2.34110481E-02f, 2.48031414E-02f, 2.62780130E-02f, + 2.78405849E-02f, 2.94960723E-02f, 3.12500000E-02f, 3.31082217E-02f, 3.50769390E-02f, + 3.71627223E-02f, 3.93725328E-02f, 4.17137454E-02f, 4.41941738E-02f, 4.68220962E-02f, + 4.96062829E-02f, 5.25560260E-02f, 5.56811699E-02f, 5.89921445E-02f, 6.25000000E-02f, + 6.62164434E-02f, 7.01538780E-02f, 7.43254447E-02f, 7.87450656E-02f, 8.34274909E-02f, + 8.83883476E-02f, 9.36441923E-02f, 9.92125657E-02f, 1.05112052E-01f, 1.11362340E-01f, + 1.17984289E-01f, 1.25000000E-01f, 1.32432887E-01f, 1.40307756E-01f, 1.48650889E-01f, + 1.57490131E-01f, 1.66854982E-01f, 1.76776695E-01f, 1.87288385E-01f, 1.98425131E-01f, + 2.10224104E-01f, 2.22724680E-01f, 2.35968578E-01f, 2.50000000E-01f, 2.64865774E-01f, + 2.80615512E-01f, 2.97301779E-01f, 3.14980262E-01f, 3.33709964E-01f, 3.53553391E-01f, + 3.74576769E-01f, 3.96850263E-01f, 4.20448208E-01f, 4.45449359E-01f, 4.71937156E-01f, + 5.00000000E-01f, 5.29731547E-01f, 5.61231024E-01f, 5.94603558E-01f, 6.29960525E-01f, + 6.67419927E-01f, 7.07106781E-01f, 7.49153538E-01f, 7.93700526E-01f, 8.40896415E-01f, + 8.90898718E-01f, 9.43874313E-01f, 1.00000000E+00f}; + +static const ia_drc_delta_gain_code_entry_struct impd_drc_delta_gain_code_table_by_size[25] = { + {2, 0x003, -0.125f}, {2, 0x002, 0.125f}, {3, 0x001, -0.250f}, {3, 0x002, 0.000f}, + {4, 0x000, -2.000f}, {5, 0x002, -0.500f}, {5, 0x00F, -0.375f}, {5, 0x00E, 1.000f}, + {6, 0x019, -0.625f}, {6, 0x018, 0.250f}, {6, 0x006, 0.375f}, {7, 0x00F, -1.000f}, + {7, 0x034, -0.875f}, {7, 0x036, -0.750f}, {7, 0x037, 0.500f}, {8, 0x01D, 0.625f}, + {9, 0x039, -1.875f}, {9, 0x0D5, -1.125f}, {9, 0x0D7, 0.750f}, {9, 0x0D4, 0.875f}, + {10, 0x070, -1.500f}, {10, 0x1AC, -1.375f}, {10, 0x1AD, -1.250f}, {11, 0x0E2, -1.750f}, + {11, 0x0E3, -1.625f}}; + +static const ia_drc_delta_gain_code_entry_struct + impd_drc_delta_gain_code_table_profile_2_by_size[49] = { + {3, 0x007, -0.125f}, {4, 0x00C, -0.625f}, {4, 0x009, -0.500f}, {4, 0x005, -0.375f}, + {4, 0x003, -0.250f}, {4, 0x001, 0.000f}, {4, 0x00B, 0.125f}, {5, 0x011, -0.875f}, + {5, 0x00E, -0.750f}, {5, 0x005, 0.250f}, {5, 0x004, 0.375f}, {5, 0x008, 0.500f}, + {5, 0x000, 0.625f}, {5, 0x00D, 0.750f}, {5, 0x00F, 0.875f}, {5, 0x010, 1.000f}, + {5, 0x01B, 1.125f}, {6, 0x02B, -1.250f}, {6, 0x028, -1.125f}, {6, 0x002, -1.000f}, + {6, 0x012, 1.250f}, {6, 0x018, 1.375f}, {6, 0x029, 1.500f}, {7, 0x06A, -4.000f}, + {7, 0x054, -1.750f}, {7, 0x068, -1.625f}, {7, 0x026, -1.500f}, {7, 0x006, -1.375f}, + {7, 0x032, 1.625f}, {8, 0x0D2, -2.250f}, {8, 0x0AB, -2.125f}, {8, 0x0AA, -2.000f}, + {8, 0x04F, -1.875f}, {8, 0x04E, 1.750f}, {8, 0x0D7, 1.875f}, {8, 0x00E, 2.000f}, + {9, 0x1AD, -3.625f}, {9, 0x1AC, -3.375f}, {9, 0x1A6, -3.250f}, {9, 0x0CD, -3.125f}, + {9, 0x0CE, -2.750f}, {9, 0x1A7, -2.625f}, {9, 0x01F, -2.500f}, {9, 0x0CC, -2.375f}, + {10, 0x03C, -3.500f}, {10, 0x19E, -3.000f}, {10, 0x19F, -2.875f}, {11, 0x07A, -3.875f}, + {11, 0x07B, -3.750f}}; + +static const ia_drc_slope_code_table_entry_struct impd_drc_slope_code_table_entry_by_value[15] = { + {6, 0x018, -3.0518f, 0}, {8, 0x042, -1.2207f, 1}, {7, 0x032, -0.4883f, 2}, + {5, 0x00A, -0.1953f, 3}, {5, 0x009, -0.0781f, 4}, {5, 0x00D, -0.0312f, 5}, + {2, 0x000, -0.005f, 6}, {1, 0x001, 0.0f, 7}, {4, 0x007, 0.005f, 8}, + {5, 0x00B, 0.0312f, 9}, {6, 0x011, 0.0781f, 10}, {9, 0x087, 0.1953f, 11}, + {9, 0x086, 0.4883f, 12}, {7, 0x020, 1.2207f, 13}, {7, 0x033, 3.0518f, 14}, +}; + +static const WORD32 k_num_delta_gain_values_table = + sizeof(impd_drc_delta_gain_code_table_by_size) / + sizeof(impd_drc_delta_gain_code_table_by_size[0]); + +static const WORD32 k_num_delta_gain_values_table_profile_2 = + sizeof(impd_drc_delta_gain_code_table_profile_2_by_size) / + sizeof(impd_drc_delta_gain_code_table_profile_2_by_size[0]); + +const ia_drc_slope_code_table_entry_struct *impd_drc_get_slope_code_table_by_value(VOID) { + return (&(impd_drc_slope_code_table_entry_by_value[0])); +} + +VOID impd_drc_get_delta_gain_code_table( + const WORD32 gain_coding_profile, + ia_drc_delta_gain_code_entry_struct const **pstr_delta_gain_code_table, WORD32 *num_entries) { + if (gain_coding_profile != GAIN_CODING_PROFILE_CLIPPING) { + *pstr_delta_gain_code_table = impd_drc_delta_gain_code_table_by_size; + *num_entries = k_num_delta_gain_values_table; + } else { + *pstr_delta_gain_code_table = impd_drc_delta_gain_code_table_profile_2_by_size; + *num_entries = k_num_delta_gain_values_table_profile_2; + } +} + +VOID impd_drc_generate_delta_time_code_table( + const WORD32 num_gain_values_max, + ia_drc_delta_time_code_table_entry_struct *pstr_delta_time_code_table) { + LOOPIDX idx; + WORD32 max_val, temp = 1; + + while ((1 << temp) < 2 * num_gain_values_max) { + temp++; + } + pstr_delta_time_code_table[0].size = -1; + pstr_delta_time_code_table[0].code = -1; + pstr_delta_time_code_table[0].value = -1; + pstr_delta_time_code_table[1].size = 2; + pstr_delta_time_code_table[1].code = 0x0; + pstr_delta_time_code_table[1].value = 1; + + for (idx = 0; idx < 4; idx++) { + pstr_delta_time_code_table[idx + 2].size = 4; + pstr_delta_time_code_table[idx + 2].code = 0x4 + idx; + pstr_delta_time_code_table[idx + 2].value = idx + 2; + } + for (idx = 0; idx < 8; idx++) { + pstr_delta_time_code_table[idx + 6].size = 5; + pstr_delta_time_code_table[idx + 6].code = 0x10 + idx; + pstr_delta_time_code_table[idx + 6].value = idx + 6; + } + + max_val = 2 * num_gain_values_max - 14 + 1; + for (idx = 0; idx < max_val; idx++) { + pstr_delta_time_code_table[idx + 14].size = 2 + temp; + pstr_delta_time_code_table[idx + 14].code = (0x3 << temp) + idx; + pstr_delta_time_code_table[idx + 14].value = idx + 14; + } +} + +FLOAT32 impd_drc_decode_slope_idx_value(const WORD32 slope_code_idx) { + const ia_drc_slope_code_table_entry_struct *pstr_slope_code_table = + impd_drc_get_slope_code_table_by_value(); + + return pstr_slope_code_table[slope_code_idx].value; +} + +FLOAT32 impd_drc_decode_slope_idx_magnitude(const WORD32 slope_code_idx) { + const ia_drc_slope_code_table_entry_struct *pstr_slope_code_table = + impd_drc_get_slope_code_table_by_value(); + + return (FLOAT32)fabs((FLOAT64)pstr_slope_code_table[slope_code_idx].value); +} diff --git a/encoder/drc_src/impd_drc_tables.h b/encoder/drc_src/impd_drc_tables.h new file mode 100644 index 0000000..56d91d7 --- /dev/null +++ b/encoder/drc_src/impd_drc_tables.h @@ -0,0 +1,62 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +extern const FLOAT32 impd_drc_downmix_coeff[16]; +extern const FLOAT32 impd_drc_downmix_coeff_lfe[16]; +extern const FLOAT32 impd_drc_channel_weight[16]; +extern const FLOAT32 impd_drc_downmix_coeff_v1[32]; +extern const FLOAT32 impd_drc_eq_slope_table[16]; +extern const FLOAT32 impd_drc_eq_gain_delta_table[32]; +extern const FLOAT32 impd_drc_zero_pole_radius_table[128]; +extern const FLOAT32 impd_drc_zero_pole_angle_table[128]; + +typedef struct { + WORD32 size; + WORD32 code; + WORD32 value; +} ia_drc_delta_time_code_table_entry_struct; + +typedef struct { + WORD32 size; + WORD32 code; + FLOAT32 value; + WORD32 index; +} ia_drc_slope_code_table_entry_struct; + +typedef struct { + WORD32 size; + WORD32 code; + FLOAT32 value; +} ia_drc_delta_gain_code_entry_struct; + +VOID impd_drc_generate_delta_time_code_table( + const WORD32 num_gain_values_max, + ia_drc_delta_time_code_table_entry_struct *delta_time_code_table_item); + +VOID impd_drc_get_delta_gain_code_table( + const WORD32 gain_coding_profile, + ia_drc_delta_gain_code_entry_struct const **pstr_delta_gain_code_table, WORD32 *num_entries); + +const ia_drc_slope_code_table_entry_struct *impd_drc_get_slope_code_table_by_value(VOID); + +FLOAT32 impd_drc_decode_slope_idx_value(const WORD32 slope_code_index); + +FLOAT32 impd_drc_decode_slope_idx_magnitude(const WORD32 slope_code_index); diff --git a/encoder/drc_src/impd_drc_uni_drc.h b/encoder/drc_src/impd_drc_uni_drc.h new file mode 100644 index 0000000..f2b4d1b --- /dev/null +++ b/encoder/drc_src/impd_drc_uni_drc.h @@ -0,0 +1,599 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +/* Defines for bitstream payload */ +#define METHOD_DEFINITION_UNKNOWN_OTHER 0 +#define METHOD_DEFINITION_PROGRAM_LOUDNESS 1 +#define METHOD_DEFINITION_ANCHOR_LOUDNESS 2 +#define METHOD_DEFINITION_MAX_OF_LOUDNESS_RANGE 3 +#define METHOD_DEFINITION_MOMENTARY_LOUDNESS_MAX 4 +#define METHOD_DEFINITION_SHORT_TERM_LOUDNESS_MAX 5 +#define METHOD_DEFINITION_LOUDNESS_RANGE 6 +#define METHOD_DEFINITION_MIXING_LEVEL 7 +#define METHOD_DEFINITION_ROOM_TYPE 8 +#define METHOD_DEFINITION_SHORT_TERM_LOUDNESS 9 + +#define MEASUREMENT_SYSTEM_BS_1770_3 2 + +#define EFFECT_BIT_NONE (-1) /* this effect bit is virtual */ +#define EFFECT_BIT_DUCK_OTHER 0x0400 +#define EFFECT_BIT_DUCK_SELF 0x0800 + +#define GAIN_CODING_PROFILE_REGULAR 0 +#define GAIN_CODING_PROFILE_FADING 1 +#define GAIN_CODING_PROFILE_CLIPPING 2 +#define GAIN_CODING_PROFILE_CONSTANT 3 + +#define GAIN_INTERPOLATION_TYPE_SPLINE 0 +#define GAIN_INTERPOLATION_TYPE_LINEAR 1 + +#define LOUDNESS_NORMALIZATION_GAIN_MAX_DEFAULT 1000 /* infinity as default */ +#define GAIN_SET_COUNT_MAX 8 /* reduced size */ + +#define LEFT_SIDE 0 +#define RIGHT_SIDE 1 +#define SPLIT_CHARACTERISTIC_COUNT_MAX 8 +#define SPLIT_CHARACTERISTIC_MAX_NODE_COUNT 4 /* one side of characteristic */ + +#define GAINFORMAT_QMF32 0x1 +#define GAINFORMAT_QMFHYBRID39 0x2 +#define GAINFORMAT_QMF64 0x3 +#define GAINFORMAT_QMFHYBRID71 0x4 +#define GAINFORMAT_QMF128 0x5 +#define GAINFORMAT_QMFHYBRID135 0x6 +#define GAINFORMAT_UNIFORM 0x7 + +#define DRC_INPUT_LOUDNESS_TARGET (-31.0f) /* dB */ + +#define SHAPE_FILTER_COUNT_MAX 8 + +#define SHAPE_FILTER_DRC_GAIN_MAX_MINUS_ONE 1583.8931924611f /* 10^3.2 - 1 */ + +#define DOWNMIX_INSTRUCTIONS_COUNT_MAX 8 /* reduced size */ +#define DRC_COEFFICIENTS_UNIDRC_V1_COUNT_MAX 2 /* reduced size */ +#define DRC_INSTRUCTIONS_UNIDRC_V1_COUNT_MAX 8 /* reduced size */ +#define SPLIT_CHARACTERISTIC_COUNT_MAX 8 /* reduced size */ +#define SHAPE_FILTER_COUNT_MAX 8 /* reduced size */ +#define ADDITIONAL_DOWNMIX_ID_COUNT_MAX MAX_ADDITIONAL_DOWNMIX_ID +#define ADDITIONAL_DRC_SET_ID_COUNT_MAX 16 +#define ADDITIONAL_EQ_SET_ID_COUNT_MAX 8 +#define LOUD_EQ_GAIN_MAX_SEQUENCE_COUNT 4 +#define FILTER_ELEMENT_COUNT_MAX 16 /* reduced size */ +#define REAL_ZERO_RADIUS_ONE_COUNT_MAX 14 +#define REAL_ZERO_COUNT_MAX 64 +#define COMPLEX_ZERO_COUNT_MAX 64 +#define REAL_POLE_COUNT_MAX 16 +#define COMPLEX_POLE_COUNT_MAX 16 +#define FIR_ORDER_MAX 128 +#define EQ_MAX_NODE_COUNT 33 +#define EQ_SUBBAND_GAIN_COUNT_MAX 135 +#define UNIQUE_SUBBAND_GAIN_COUNT_MAX 16 /* reduced size */ +#define FILTER_BLOCK_COUNT_MAX 16 +#define FILTER_ELEMENT_COUNT_MAX 16 /* reduced size */ +#define UNIQUE_SUBBAND_GAINS_COUNT_MAX 8 /* reduced size */ +#define EQ_MAX_CHANNEL_GROUP_COUNT 4 /* reduced size */ +#define EQ_FILTER_BLOCK_COUNT_MAX 4 /* reduced size */ +#define LOUD_EQ_INSTRUCTIONS_COUNT_MAX 8 /* reduced size */ +#define EQ_INSTRUCTIONS_COUNT_MAX 8 + +#define DRC_COMPLEXITY_LEVEL_MAX 15 +#define EQ_COMPLEXITY_LEVEL_MAX 15 +#define COMPLEXITY_W_SUBBAND_EQ 2.5f +#define COMPLEXITY_W_FIR 0.4f +#define COMPLEXITY_W_IIR 5.0f +#define COMPLEXITY_W_MOD_TIME 1.0f +#define COMPLEXITY_W_MOD_SUBBAND 2.0f +#define COMPLEXITY_W_LAP 2.0f +#define COMPLEXITY_W_SHAPE 6.0f +#define COMPLEXITY_W_SPLINE 5.0f +#define COMPLEXITY_W_LINEAR 2.5f +#define COMPLEXITY_W_PARAM_DRC_FILT 5.0f +#define COMPLEXITY_W_PARAM_DRC_SUBBAND 5.0f +#define COMPLEXITY_W_PARAM_LIM_FILT 4.5f +#define COMPLEXITY_W_PARAM_DRC_ATTACK 136.0f + +typedef struct { + WORD32 level_estim_k_weighting_type; + WORD32 level_estim_integration_time_present; + WORD32 level_estim_integration_time; + WORD32 drc_curve_definition_type; + WORD32 drc_characteristic; + WORD32 node_count; + WORD32 node_level[MAX_PARAM_DRC_TYPE_FF_NODE_COUNT]; + WORD32 node_gain[MAX_PARAM_DRC_TYPE_FF_NODE_COUNT]; + WORD32 drc_gain_smooth_parameters_present; + WORD32 gain_smooth_attack_time_slow; + WORD32 gain_smooth_release_time_slow; + WORD32 gain_smooth_time_fast_present; + WORD32 gain_smooth_attack_time_fast; + WORD32 gain_smooth_release_time_fast; + WORD32 gain_smooth_threshold_present; + WORD32 gain_smooth_attack_threshold; + WORD32 gain_smooth_release_threshold; + WORD32 gain_smooth_hold_off_count_present; + WORD32 gain_smooth_hold_off; + WORD32 disable_paramtric_drc; +} ia_drc_parametric_drc_type_feed_forward_struct; + +typedef struct { + WORD32 parametric_lim_threshold_present; + FLOAT32 parametric_lim_threshold; + WORD32 parametric_lim_attack; + WORD32 parametric_lim_release_present; + WORD32 parametric_lim_release; + WORD32 drc_characteristic; + WORD32 disable_paramtric_drc; +} ia_drc_parametric_drc_type_lim_struct; + +typedef struct { + WORD32 parametric_drc_id; + WORD32 parametric_drc_look_ahead_present; + WORD32 parametric_drc_look_ahead; + WORD32 parametric_drc_preset_id_present; + WORD32 parametric_drc_preset_id; + WORD32 parametric_drc_type; + WORD32 len_bit_size; + ia_drc_parametric_drc_type_feed_forward_struct str_parametric_drc_type_feed_forward; + ia_drc_parametric_drc_type_lim_struct str_parametric_drc_type_lim; + WORD32 disable_paramtric_drc; +} ia_drc_parametric_drc_instructions_struct; + +typedef struct { + WORD32 parametric_drc_id; + WORD32 side_chain_config_type; + WORD32 downmix_id; + WORD32 level_estim_channel_weight_format; + FLOAT32 level_estim_channel_weight[MAX_CHANNEL_COUNT]; + WORD32 drc_input_loudness_present; + FLOAT32 drc_input_loudness; + + /* derived data */ + WORD32 channel_count_drom_downmix_id; +} ia_drc_parametric_drc_gain_set_params_struct; + +typedef struct { + WORD32 drc_location; + WORD32 parametric_drc_frame_size_format; + WORD32 parametric_drc_frame_size; + WORD32 parametric_drc_delay_max_present; + WORD32 parametric_drc_delay_max; + WORD32 reset_parametric_drc; + WORD32 parametric_drc_gain_set_count; + ia_drc_parametric_drc_gain_set_params_struct parametric_drc_gain_set_params[MAX_SEQUENCE_COUNT]; +} ia_drc_coeff_parametric_drc_struct; + +typedef struct { + WORD32 base_ch_count; + WORD32 layout_signaling_present; + WORD32 defined_layout; + WORD32 speaker_position[MAX_SPEAKER_POS_COUNT]; +} ia_drc_channel_layout_struct; + +typedef struct { + WORD32 downmix_id; + WORD32 target_ch_count; + WORD32 target_layout; + WORD32 downmix_coefficients_present; + FLOAT32 downmix_coeff[MAX_DOWNMIX_COEFF_COUNT]; +} ia_drc_downmix_instructions_struct; + +typedef struct { + FLOAT32 x; + FLOAT32 y; +} ia_drc_gain_points_struct; + +typedef struct { + WORD32 gain_sequence_index; + WORD32 drc_characteristic_present; + WORD32 drc_characteristic_format_is_cicp; + WORD32 drc_characteristic; + WORD32 drc_characteristic_left_index; + WORD32 drc_characteristic_right_index; + WORD32 crossover_freq_index; + WORD32 start_sub_band_index; + WORD32 nb_points; + FLOAT32 width; + FLOAT32 attack; + FLOAT32 decay; + ia_drc_gain_points_struct gain_points[512]; +} ia_drc_gain_params_struct; + +typedef struct { + WORD32 ducking_scaling_present; + FLOAT32 ducking_scaling; + FLOAT32 ducking_scaling_quantized; +} ia_drc_ducking_modifiers_struct; + +typedef struct { + WORD32 target_characteristic_left_present[MAX_BAND_COUNT]; + WORD32 target_characteristic_left_index[MAX_BAND_COUNT]; + WORD32 target_characteristic_right_present[MAX_BAND_COUNT]; + WORD32 target_characteristic_right_index[MAX_BAND_COUNT]; + WORD32 shape_filter_present; + WORD32 shape_filter_index; + + WORD32 gain_scaling_present[MAX_BAND_COUNT]; + FLOAT32 attenuation_scaling[MAX_BAND_COUNT]; + FLOAT32 amplification_scaling[MAX_BAND_COUNT]; + WORD32 gain_offset_present[MAX_BAND_COUNT]; + FLOAT32 gain_offset[MAX_BAND_COUNT]; + +} ia_drc_gain_modifiers_struct; + +typedef struct { + WORD32 gain_coding_profile; + WORD32 gain_interpolation_type; + WORD32 full_frame; + WORD32 time_alignment; + WORD32 time_delta_min_present; + WORD32 delta_tmin; + WORD32 band_count; + WORD32 drc_band_type; + ia_drc_gain_params_struct gain_params[MAX_BAND_COUNT]; +} ia_drc_gain_set_params_struct; + +typedef struct { + WORD32 characteristic_format; + WORD32 bs_gain; + WORD32 bs_io_ratio; + WORD32 bs_exp; + WORD32 flip_sign; + WORD32 characteristic_node_count; + FLOAT32 node_level[SPLIT_CHARACTERISTIC_MAX_NODE_COUNT + 1]; + FLOAT32 node_gain[SPLIT_CHARACTERISTIC_MAX_NODE_COUNT + 1]; +} ia_drc_split_drc_characteristic_struct; + +typedef struct { + WORD32 corner_freq_index; + WORD32 filter_strength_index; +} ia_drc_shape_filter_params_struct; + +typedef struct { + WORD32 lf_cut_filter_present; + ia_drc_shape_filter_params_struct str_lf_cut_params; + WORD32 lf_boost_filter_present; + ia_drc_shape_filter_params_struct str_lf_boost_params; + WORD32 hf_cut_filter_present; + ia_drc_shape_filter_params_struct str_hf_cut_params; + WORD32 hf_boost_filter_present; + ia_drc_shape_filter_params_struct str_hf_boost_params; +} ia_drc_shape_filter_block_params_struct; + +typedef struct { + WORD32 drc_location; + WORD32 drc_characteristic; +} ia_drc_coefficients_basic_struct; + +typedef struct { + WORD32 drc_location; + WORD32 drc_frame_size_present; + WORD32 drc_frame_size; + WORD32 drc_characteristic_left_present; + WORD32 characteristic_left_count; + ia_drc_split_drc_characteristic_struct + str_split_characteristic_left[SPLIT_CHARACTERISTIC_COUNT_MAX + 1]; + WORD32 drc_characteristic_right_present; + WORD32 characteristic_right_count; + ia_drc_split_drc_characteristic_struct + str_split_characteristic_right[SPLIT_CHARACTERISTIC_COUNT_MAX]; + WORD32 shape_filters_present; + WORD32 shape_filter_count; + ia_drc_shape_filter_block_params_struct + str_shape_filter_block_params[SHAPE_FILTER_COUNT_MAX + 1]; + WORD32 gain_sequence_count; + WORD32 gain_set_count; + ia_drc_gain_set_params_struct str_gain_set_params[GAIN_SET_COUNT_MAX]; +} ia_drc_coefficients_uni_drc_struct; + +typedef struct { + WORD32 drc_set_id; + WORD32 drc_location; + WORD32 downmix_id; + WORD32 additional_downmix_id_present; + WORD32 additional_downmix_id_count; + WORD32 additional_downmix_id[MAX_ADDITIONAL_DOWNMIX_ID]; + WORD32 drc_set_effect; + WORD32 limiter_peak_target_present; + FLOAT32 limiter_peak_target; + WORD32 drc_set_target_loudness_present; + WORD32 drc_set_target_loudness_value_upper; + WORD32 drc_set_target_loudness_value_lower_present; + WORD32 drc_set_target_loudness_value_lower; +} ia_drc_instructions_basic_struct; + +typedef struct { + WORD32 drc_set_id; + WORD32 drc_set_complexity_level; + WORD32 drc_apply_to_downmix; + WORD32 requires_eq; + WORD32 downmix_id_present; + WORD32 drc_location; + WORD32 downmix_id; + WORD32 additional_downmix_id_present; + WORD32 additional_downmix_id_count; + WORD32 additional_downmix_id[MAX_ADDITIONAL_DOWNMIX_ID]; + WORD32 depends_on_drc_set_present; + WORD32 depends_on_drc_set; + WORD32 no_independent_use; + WORD32 drc_set_effect; + WORD32 gain_set_index[MAX_CHANNEL_COUNT]; + ia_drc_gain_modifiers_struct str_gain_modifiers[MAX_CHANNEL_GROUP_COUNT]; + ia_drc_ducking_modifiers_struct str_ducking_modifiers_for_channel[MAX_CHANNEL_COUNT]; + WORD32 limiter_peak_target_present; + FLOAT32 limiter_peak_target; + WORD32 drc_set_target_loudness_present; + WORD32 drc_set_target_loudness_value_upper; + WORD32 drc_set_target_loudness_value_lower_present; + WORD32 drc_set_target_loudness_value_lower; + WORD32 drc_instructions_type; + WORD32 mae_group_id; + WORD32 mae_group_preset_id; + + WORD32 drc_channel_count; + WORD32 num_drc_channel_groups; + WORD32 gain_set_index_for_channel_group[MAX_CHANNEL_GROUP_COUNT]; + WORD32 band_count_for_channel_group[MAX_CHANNEL_GROUP_COUNT]; + WORD32 gain_coding_profile_for_channel_group[MAX_CHANNEL_GROUP_COUNT]; + WORD32 gain_interpolation_type_for_channel_group[MAX_CHANNEL_GROUP_COUNT]; + WORD32 time_delta_min_for_channel_group[MAX_CHANNEL_GROUP_COUNT]; + WORD32 time_alignment_for_channel_group[MAX_CHANNEL_GROUP_COUNT]; + ia_drc_ducking_modifiers_struct + str_ducking_modifiers_for_channel_group[MAX_CHANNEL_GROUP_COUNT]; + WORD32 channel_group_for_channel[MAX_CHANNEL_COUNT]; + WORD32 num_channels_per_channel_group[MAX_CHANNEL_GROUP_COUNT]; + WORD32 gain_element_count; + WORD32 multiband_audio_signal_count; + WORD32 channel_group_is_parametric_drc[MAX_CHANNEL_GROUP_COUNT]; + WORD32 gain_set_idx_for_ch_group_parametric_drc[MAX_CHANNEL_GROUP_COUNT]; +} ia_drc_instructions_uni_drc; + +typedef struct { + WORD32 method_definition; + FLOAT32 method_value; + WORD32 measurement_system; + WORD32 reliability; +} ia_drc_loudness_measure_struct; + +typedef struct { + WORD32 drc_set_id; + WORD32 eq_set_id; + WORD32 downmix_id; + WORD32 sample_peak_level_present; + FLOAT32 sample_peak_level; + WORD32 true_peak_level_present; + FLOAT32 true_peak_level; + WORD32 true_peak_level_measurement_system; + WORD32 true_peak_level_reliability; + WORD32 measurement_count; + ia_drc_loudness_measure_struct str_loudness_measure[MAX_MEASUREMENT_COUNT]; + WORD32 loudness_info_type; + WORD32 mae_group_id; + WORD32 mae_group_preset_id; +} ia_drc_loudness_info_struct; + +typedef struct { + WORD32 loud_eq_set_id; + WORD32 drc_location; + WORD32 downmix_id_present; + WORD32 downmix_id; + WORD32 additional_downmix_id_present; + WORD32 additional_downmix_id_count; + WORD32 additional_downmix_id[ADDITIONAL_DOWNMIX_ID_COUNT_MAX]; + WORD32 drc_set_id_present; + WORD32 drc_set_id; + WORD32 additional_drc_set_id_present; + WORD32 additional_drc_set_id_count; + WORD32 additional_drc_set_id[ADDITIONAL_DRC_SET_ID_COUNT_MAX]; + WORD32 eq_set_id_present; + WORD32 eq_set_id; + WORD32 additional_eq_set_id_present; + WORD32 additional_eq_set_id_count; + WORD32 additional_eq_set_id[ADDITIONAL_EQ_SET_ID_COUNT_MAX]; + WORD32 loudness_after_drc; + WORD32 loudness_after_eq; + WORD32 loud_eq_gain_sequence_count; + WORD32 gain_sequence_index[LOUD_EQ_GAIN_MAX_SEQUENCE_COUNT]; + WORD32 drc_characteristic_format_is_cicp[LOUD_EQ_GAIN_MAX_SEQUENCE_COUNT]; + WORD32 drc_characteristic[LOUD_EQ_GAIN_MAX_SEQUENCE_COUNT]; + WORD32 drc_characteristic_left_index[LOUD_EQ_GAIN_MAX_SEQUENCE_COUNT]; + WORD32 drc_characteristic_right_index[LOUD_EQ_GAIN_MAX_SEQUENCE_COUNT]; + WORD32 frequency_range_index[LOUD_EQ_GAIN_MAX_SEQUENCE_COUNT]; + FLOAT32 loud_eq_scaling[LOUD_EQ_GAIN_MAX_SEQUENCE_COUNT]; + FLOAT32 loud_eq_offset[LOUD_EQ_GAIN_MAX_SEQUENCE_COUNT]; +} ia_drc_loud_eq_instructions_struct; + +typedef struct { + WORD32 filter_element_index; + WORD32 filter_element_gain_present; + FLOAT32 filter_element_gain; +} ia_drc_filter_element_struct; + +typedef struct { + WORD32 filter_element_count; + ia_drc_filter_element_struct filter_element[FILTER_ELEMENT_COUNT_MAX]; +} ia_drc_filter_block_struct; + +typedef struct { + WORD32 eq_filter_format; + WORD32 real_zero_radius_one_count; + WORD32 real_zero_count; + WORD32 generic_zero_count; + WORD32 real_pole_count; + WORD32 complex_pole_count; + FLOAT32 zero_sign[REAL_ZERO_RADIUS_ONE_COUNT_MAX]; + FLOAT32 real_zero_radius[REAL_ZERO_COUNT_MAX]; + FLOAT32 generic_zero_radius[COMPLEX_ZERO_COUNT_MAX]; + FLOAT32 generic_zero_angle[COMPLEX_ZERO_COUNT_MAX]; + FLOAT32 real_pole_radius[REAL_POLE_COUNT_MAX]; + FLOAT32 complex_pole_radius[COMPLEX_POLE_COUNT_MAX]; + FLOAT32 complex_pole_angle[COMPLEX_POLE_COUNT_MAX]; + WORD32 fir_filter_order; + WORD32 fir_symmetry; + FLOAT32 fir_coefficient[FIR_ORDER_MAX / 2]; +} ia_drc_unique_td_filter_element_struct; + +typedef struct { + WORD32 n_eq_nodes; + FLOAT32 eq_slope[EQ_MAX_NODE_COUNT]; + WORD32 eq_freq_delta[EQ_MAX_NODE_COUNT]; + FLOAT32 eq_gain_initial; + FLOAT32 eq_gain_delta[EQ_MAX_NODE_COUNT]; +} ia_drc_eq_subband_gain_spline_struct; + +typedef struct { + WORD32 eq_subband_gain[EQ_SUBBAND_GAIN_COUNT_MAX]; +} ia_drc_eq_subband_gain_vector_struct; + +typedef struct { + WORD32 eq_delay_max_present; + WORD32 eq_delay_max; + WORD32 unique_filter_block_count; + ia_drc_filter_block_struct str_filter_block[FILTER_BLOCK_COUNT_MAX]; + WORD32 unique_td_filter_element_count; + ia_drc_unique_td_filter_element_struct str_unique_td_filter_element[FILTER_ELEMENT_COUNT_MAX]; + WORD32 unique_eq_subband_gains_count; + WORD32 eq_subband_gain_representation; + WORD32 eq_subband_gain_format; + WORD32 eq_subband_gain_count; + ia_drc_eq_subband_gain_spline_struct str_eq_subband_gain_spline[UNIQUE_SUBBAND_GAIN_COUNT_MAX]; + ia_drc_eq_subband_gain_vector_struct str_eq_subband_gain_vector[UNIQUE_SUBBAND_GAIN_COUNT_MAX]; +} ia_drc_eq_coefficients_struct; + +typedef struct { + WORD32 filter_block_count; + WORD32 filter_block_index[EQ_FILTER_BLOCK_COUNT_MAX]; +} ia_drc_filter_block_refs_struct; + +typedef struct { + WORD32 eq_cascade_gain_present[EQ_MAX_CHANNEL_GROUP_COUNT]; + WORD32 eq_cascade_gain[EQ_MAX_CHANNEL_GROUP_COUNT]; + ia_drc_filter_block_refs_struct str_filter_block_refs[EQ_MAX_CHANNEL_GROUP_COUNT]; + WORD32 eq_phase_alignment_present; + WORD32 eq_phase_alignment[EQ_MAX_CHANNEL_GROUP_COUNT][EQ_MAX_CHANNEL_GROUP_COUNT]; +} ia_drc_td_filter_cascade_struct; + +typedef struct { + WORD32 eq_set_id; + WORD32 eq_set_complexity_level; + WORD32 downmix_id_present; + WORD32 downmix_id; + WORD32 eq_apply_to_downmix; + WORD32 additional_downmix_id_present; + WORD32 additional_downmix_id_count; + WORD32 additional_downmix_id[ADDITIONAL_DOWNMIX_ID_COUNT_MAX]; + WORD32 drc_set_id; + WORD32 additional_drc_set_id_present; + WORD32 additional_drc_set_id_count; + WORD32 additional_drc_set_id[ADDITIONAL_DRC_SET_ID_COUNT_MAX]; + WORD32 eq_set_purpose; + WORD32 depends_on_eq_set_present; + WORD32 depends_on_eq_set; + WORD32 no_independent_eq_use; + WORD32 eq_channel_count; + WORD32 eq_channel_group_count; + WORD32 eq_channel_group_for_channel[MAX_CHANNEL_COUNT]; + WORD32 td_filter_cascade_present; + ia_drc_td_filter_cascade_struct str_td_filter_cascade; + WORD32 subband_gains_present; + WORD32 subband_gains_index[EQ_MAX_CHANNEL_GROUP_COUNT]; + WORD32 eq_transition_duration_present; + FLOAT32 eq_transition_duration; +} ia_drc_eq_instructions_struct; + +typedef struct { + WORD32 uni_drc_config_ext_type[MAX_EXT_COUNT]; + WORD32 ext_bit_size[MAX_EXT_COUNT - 1]; + /* UNIDRC_CONF_EXT_PARAM_DRC */ + WORD32 parametric_drc_present; + ia_drc_coeff_parametric_drc_struct str_drc_coeff_parametric_drc; + WORD32 parametric_drc_instructions_count; + ia_drc_parametric_drc_instructions_struct + str_parametric_drc_instructions[MAX_PARAM_DRC_INSTRUCTIONS_COUNT]; + + /* UNIDRC_CONF_EXT_V1 */ + WORD32 drc_extension_v1_present; + WORD32 downmix_instructions_v1_present; + WORD32 downmix_instructions_v1_count; + ia_drc_downmix_instructions_struct str_downmix_instructions_v1[DOWNMIX_INSTRUCTIONS_COUNT_MAX]; + WORD32 drc_coeffs_and_instructions_uni_drc_v1_present; + WORD32 drc_coefficients_uni_drc_v1_count; + ia_drc_coefficients_uni_drc_struct + str_drc_coefficients_uni_drc_v1[DRC_COEFFICIENTS_UNIDRC_V1_COUNT_MAX]; + WORD32 drc_instructions_uni_drc_v1_count; + ia_drc_instructions_uni_drc + str_drc_instructions_uni_drc_v1[DRC_INSTRUCTIONS_UNIDRC_V1_COUNT_MAX]; + WORD32 loud_eq_instructions_present; + WORD32 loud_eq_instructions_count; + ia_drc_loud_eq_instructions_struct str_loud_eq_instructions[LOUD_EQ_INSTRUCTIONS_COUNT_MAX]; + WORD32 eq_present; + ia_drc_eq_coefficients_struct str_eq_coefficients; + WORD32 eq_instructions_count; + ia_drc_eq_instructions_struct str_eq_instructions[EQ_INSTRUCTIONS_COUNT_MAX]; +} ia_drc_uni_drc_config_ext_struct; + +typedef struct { + WORD32 sample_rate_present; + WORD32 sample_rate; + WORD32 downmix_instructions_count; + WORD32 drc_coefficients_uni_drc_count; + WORD32 drc_instructions_uni_drc_count; + WORD32 drc_instructions_count_plus; + WORD32 drc_description_basic_present; + WORD32 drc_coefficients_basic_count; + WORD32 drc_instructions_basic_count; + WORD32 uni_drc_config_ext_present; + ia_drc_uni_drc_config_ext_struct str_uni_drc_config_ext; + ia_drc_coefficients_basic_struct str_drc_coefficients_basic[MAX_DRC_COEFF_COUNT]; + ia_drc_instructions_basic_struct str_drc_instructions_basic[MAX_DRC_INSTRUCTIONS_COUNT]; + ia_drc_coefficients_uni_drc_struct str_drc_coefficients_uni_drc[MAX_DRC_COEFF_COUNT]; + ia_drc_instructions_uni_drc str_drc_instructions_uni_drc[MAX_DRC_INSTRUCTIONS_COUNT]; + ia_drc_channel_layout_struct str_channel_layout; + ia_drc_downmix_instructions_struct str_downmix_instructions[MAX_DOWNMIX_INSTRUCTION_COUNT]; + WORD32 loudness_info_set_present; +} ia_drc_uni_drc_config_struct; + +typedef struct { + WORD32 loudness_info_v1_album_count; + WORD32 loudness_info_v1_count; + ia_drc_loudness_info_struct str_loudness_info_v1_album[MAX_LOUDNESS_INFO_COUNT]; + ia_drc_loudness_info_struct str_loudness_info_v1[MAX_LOUDNESS_INFO_COUNT]; +} ia_drc_loudness_info_set_ext_eq_struct; + +typedef struct { + WORD32 loudness_info_set_ext_type[MAX_EXT_COUNT]; + WORD32 ext_bit_size[MAX_EXT_COUNT - 1]; + ia_drc_loudness_info_set_ext_eq_struct str_loudness_info_set_ext_eq; +} ia_drc_loudness_info_set_extension_struct; + +typedef struct { + WORD32 loudness_info_album_count; + WORD32 loudness_info_count; + WORD32 loudness_info_set_ext_present; + ia_drc_loudness_info_struct str_loudness_info_album[MAX_LOUDNESS_INFO_COUNT]; + ia_drc_loudness_info_struct str_loudness_info[MAX_LOUDNESS_INFO_COUNT]; + ia_drc_loudness_info_set_extension_struct str_loudness_info_set_extension; +} ia_drc_loudness_info_set_struct; + +typedef struct { + WORD32 uni_drc_gain_ext_present; + WORD32 uni_drc_gain_ext_type[MAX_EXT_COUNT]; + WORD32 ext_bit_size[MAX_EXT_COUNT - 1]; +} ia_drc_uni_drc_gain_ext_struct; diff --git a/encoder/drc_src/impd_drc_uni_drc_eq.c b/encoder/drc_src/impd_drc_uni_drc_eq.c new file mode 100644 index 0000000..2625ea4 --- /dev/null +++ b/encoder/drc_src/impd_drc_uni_drc_eq.c @@ -0,0 +1,1439 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include +#include "ixheaac_type_def.h" +#include "ixheaac_error_standards.h" +#include "ixheaace_error_codes.h" + +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_uni_drc_eq.h" + +static IA_ERRORCODE impd_drc_derive_subband_center_freq(const WORD32 eq_subband_gain_count, + const WORD32 eq_subband_gain_format, + const FLOAT32 audio_sample_rate, + FLOAT32 *ptr_subband_center_freq) { + LOOPIDX idx; + FLOAT32 width, offset; + + switch (eq_subband_gain_format) { + case GAINFORMAT_QMF32: + case GAINFORMAT_QMF64: + case GAINFORMAT_QMF128: + case GAINFORMAT_UNIFORM: + width = 0.5f * audio_sample_rate / (FLOAT32)eq_subband_gain_count; + offset = 0.5f * width; + for (idx = 0; idx < eq_subband_gain_count; idx++) { + ptr_subband_center_freq[idx] = idx * width + offset; + } + break; + case GAINFORMAT_QMFHYBRID39: + case GAINFORMAT_QMFHYBRID71: + case GAINFORMAT_QMFHYBRID135: + return IA_EXHEAACE_CONFIG_FATAL_DRC_UNSUPPORTED_CONFIG; + break; + default: + break; + } + + return IA_NO_ERROR; +} + +static VOID impd_drc_derive_zero_response(const FLOAT32 radius, const FLOAT32 angle_radian, + const FLOAT32 frequency_radian, FLOAT32 *response) { + *response = + (FLOAT32)(1.0f + radius * radius - 2.0f * radius * cos(frequency_radian - angle_radian)); +} + +static VOID impd_drc_derive_pole_response(const FLOAT32 radius, const FLOAT32 angle_radian, + const FLOAT32 frequency_radian, FLOAT32 *response) { + *response = + (FLOAT32)(1.0f + radius * radius - 2.0f * radius * cos(frequency_radian - angle_radian)); + *response = 1.0f / *response; +} + +static VOID impd_drc_derive_fir_filter_response(const WORD32 fir_order, const WORD32 fir_symmetry, + const FLOAT32 *ptr_fir_coeff, + const FLOAT32 frequency_radian, + FLOAT32 *response) { + LOOPIDX idx; + WORD32 order_2; + FLOAT32 sum = 0.0f; + + if ((fir_order & 0x1) != 0) { + order_2 = (fir_order + 1) / 2; + if (fir_symmetry != 0) { + for (idx = 1; idx <= order_2; idx++) { + sum += (FLOAT32)(ptr_fir_coeff[order_2 - idx] * sin((idx - 0.5f) * frequency_radian)); + } + } else { + for (idx = 1; idx <= order_2; idx++) { + sum += (FLOAT32)(ptr_fir_coeff[order_2 - idx] * cos((idx - 0.5f) * frequency_radian)); + } + } + sum *= 2.0f; + } else { + order_2 = fir_order / 2; + if (fir_symmetry != 0) { + for (idx = 1; idx <= order_2; idx++) { + sum += (FLOAT32)(ptr_fir_coeff[order_2 - idx] * sin(idx * frequency_radian)); + } + sum *= 2.0f; + } else { + sum = ptr_fir_coeff[order_2]; + } + } + + *response = sum; +} + +static VOID impd_drc_derive_filter_element_response( + ia_drc_unique_td_filter_element_struct *pstr_unique_td_filter_element, + const FLOAT32 frequency_radian, FLOAT32 *response) { + LOOPIDX idx; + FLOAT32 response_part, radius, angle_radian; + FLOAT64 combined_response = 1.0; + + if (pstr_unique_td_filter_element->eq_filter_format != FILTER_ELEMENT_FORMAT_POLE_ZERO) { + impd_drc_derive_fir_filter_response(pstr_unique_td_filter_element->fir_filter_order, + pstr_unique_td_filter_element->fir_symmetry, + pstr_unique_td_filter_element->fir_coefficient, + frequency_radian, &response_part); + combined_response *= response_part; + } else { + for (idx = 0; idx < pstr_unique_td_filter_element->real_zero_radius_one_count; idx++) { + impd_drc_derive_zero_response(1.0f, + (FLOAT32)(M_PI)*pstr_unique_td_filter_element->zero_sign[idx], + frequency_radian, &response_part); + combined_response *= response_part; + } + for (idx = 0; idx < pstr_unique_td_filter_element->real_zero_count; idx++) { + if (pstr_unique_td_filter_element->real_zero_radius[idx] >= 0.0f) { + radius = pstr_unique_td_filter_element->real_zero_radius[idx]; + angle_radian = 0.0f; + } else { + radius = -pstr_unique_td_filter_element->real_zero_radius[idx]; + angle_radian = (FLOAT32)(M_PI); + } + impd_drc_derive_zero_response(radius, angle_radian, frequency_radian, &response_part); + combined_response *= response_part; + impd_drc_derive_zero_response(1.0f / radius, angle_radian, frequency_radian, + &response_part); + combined_response *= response_part; + } + + combined_response = sqrt(combined_response); + + for (idx = 0; idx < pstr_unique_td_filter_element->generic_zero_count; idx++) { + radius = pstr_unique_td_filter_element->generic_zero_radius[idx]; + + impd_drc_derive_zero_response( + radius, (FLOAT32)(M_PI)*pstr_unique_td_filter_element->generic_zero_angle[idx], + frequency_radian, &response_part); + combined_response *= response_part; + + impd_drc_derive_zero_response( + 1.0f / radius, (FLOAT32)(M_PI)*pstr_unique_td_filter_element->generic_zero_angle[idx], + frequency_radian, &response_part); + combined_response *= response_part; + } + for (idx = 0; idx < pstr_unique_td_filter_element->real_pole_count; idx++) { + if (pstr_unique_td_filter_element->real_pole_radius[idx] >= 0.0f) { + radius = pstr_unique_td_filter_element->real_pole_radius[idx]; + angle_radian = 0.0f; + } else { + radius = -pstr_unique_td_filter_element->real_pole_radius[idx]; + angle_radian = (FLOAT32)(-M_PI); + } + impd_drc_derive_pole_response(radius, angle_radian, frequency_radian, &response_part); + combined_response *= response_part; + } + for (idx = 0; idx < pstr_unique_td_filter_element->complex_pole_count; idx++) { + impd_drc_derive_pole_response( + pstr_unique_td_filter_element->real_pole_radius[idx], + (FLOAT32)(M_PI)*pstr_unique_td_filter_element->complex_pole_angle[idx], + frequency_radian, &response_part); + combined_response *= response_part * response_part; + } + } + + *response = (FLOAT32)combined_response; +} + +static VOID impd_drc_derive_filter_block_response( + ia_drc_unique_td_filter_element_struct *pstr_unique_td_filter_element, + ia_drc_filter_block_struct *pstr_filter_block, const FLOAT32 frequency_radian, + FLOAT32 *response) { + LOOPIDX idx; + FLOAT32 response_part; + FLOAT64 combined_response = 1.0; + ia_drc_filter_element_struct *pstr_filter_element; + + for (idx = 0; idx < pstr_filter_block->filter_element_count; idx++) { + pstr_filter_element = &pstr_filter_block->filter_element[idx]; + impd_drc_derive_filter_element_response( + &(pstr_unique_td_filter_element[pstr_filter_element->filter_element_index]), + frequency_radian, &response_part); + combined_response *= response_part; + + if (pstr_filter_element->filter_element_gain_present == 1) { + combined_response *= pow(10.0f, 0.05f * pstr_filter_element->filter_element_gain); + } + } + + *response = (FLOAT32)combined_response; +} + +static IA_ERRORCODE impd_drc_derive_subband_gains_from_td_cascade( + ia_drc_unique_td_filter_element_struct *pstr_unique_td_filter_element, + ia_drc_filter_block_struct *pstr_filter_block, + ia_drc_td_filter_cascade_struct *pstr_td_filter_cascade, const WORD32 eq_subband_gain_format, + const WORD32 eq_channel_group_count, const FLOAT32 audio_sample_rate, + const WORD32 eq_frame_size_subband, ia_drc_subband_filter_struct *pstr_subband_filter, + VOID *ptr_scratch) { + IA_ERRORCODE err_code = IA_NO_ERROR; + LOOPIDX i, j, k; + WORD32 eq_subband_gain_count = pstr_subband_filter->coeff_count; + FLOAT32 response_part, frequency_radian; + FLOAT32 *ptr_subband_center_freq = (FLOAT32 *)ptr_scratch; + FLOAT64 combined_response; + + err_code = impd_drc_derive_subband_center_freq(eq_subband_gain_count, eq_subband_gain_format, + audio_sample_rate, ptr_subband_center_freq); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + + for (i = 0; i < eq_channel_group_count; i++) { + for (j = 0; j < eq_subband_gain_count; j++) { + combined_response = pow(10.0f, 0.05f * pstr_td_filter_cascade->eq_cascade_gain[i]); + frequency_radian = 2.0f * (FLOAT32)M_PI * ptr_subband_center_freq[j] / audio_sample_rate; + + for (k = 0; k < pstr_td_filter_cascade->str_filter_block_refs[i].filter_block_count; k++) { + impd_drc_derive_filter_block_response( + pstr_unique_td_filter_element, + &(pstr_filter_block[pstr_td_filter_cascade->str_filter_block_refs[i] + .filter_block_index[k]]), + frequency_radian, &response_part); + combined_response *= response_part; + } + pstr_subband_filter[i].subband_coeff[j] = (FLOAT32)combined_response; + } + pstr_subband_filter[i].eq_frame_size_subband = eq_frame_size_subband; + } + + return err_code; +} + +static VOID impd_drc_check_presence_and_add_cascade( + ia_drc_cascade_alignment_group_struct *pstr_cascade_alignment_group, const WORD32 index_c1, + const WORD32 index_c2, WORD32 *done) { + LOOPIDX i, j; + + *done = 0; + for (i = 0; i < pstr_cascade_alignment_group->member_count; i++) { + if (pstr_cascade_alignment_group->member_index[i] == index_c1) { + for (j = 0; j < pstr_cascade_alignment_group->member_count; j++) { + if (pstr_cascade_alignment_group->member_index[j] == index_c2) { + *done = 1; + } + } + if (*done == 0) { + pstr_cascade_alignment_group->member_index[pstr_cascade_alignment_group->member_count] = + index_c2; + pstr_cascade_alignment_group->member_count++; + *done = 1; + } + } + } +} + +static VOID impd_drc_derive_cascade_alignment_groups( + const WORD32 eq_channel_group_count, const WORD32 eq_phase_alignment_present, + const WORD32 eq_phase_alignment[EQ_MAX_CHANNEL_GROUP_COUNT][EQ_MAX_CHANNEL_GROUP_COUNT], + WORD32 *cascade_alignment_group_count, + ia_drc_cascade_alignment_group_struct *pstr_cascade_alignment_group) { + LOOPIDX i, j, k; + WORD32 group_count = 0, done; + + if (eq_phase_alignment_present != 0) { + for (i = 0; i < eq_channel_group_count; i++) { + for (j = i + 1; j < eq_channel_group_count; j++) { + if (eq_phase_alignment[i][j] == 1) { + done = 0; + for (k = 0; k < group_count; k++) { + impd_drc_check_presence_and_add_cascade(&pstr_cascade_alignment_group[k], i, j, + &done); + if (done == 0) { + impd_drc_check_presence_and_add_cascade(&pstr_cascade_alignment_group[k], j, i, + &done); + } + } + if (done == 0) { + pstr_cascade_alignment_group[group_count].member_count = 2; + pstr_cascade_alignment_group[group_count].member_index[0] = i; + pstr_cascade_alignment_group[group_count].member_index[1] = j; + group_count++; + } + } + } + } + } else { + if (eq_channel_group_count > 1) { + for (i = 0; i < eq_channel_group_count; i++) { + pstr_cascade_alignment_group[group_count].member_index[i] = i; + } + pstr_cascade_alignment_group[group_count].member_count = eq_channel_group_count; + group_count = 1; + } + } + + *cascade_alignment_group_count = group_count; +} + +static IA_ERRORCODE impd_drc_derive_allpass_chain( + ia_drc_filter_cascade_t_domain_struct *pstr_filter_cascade_t_domain, + ia_drc_allpass_chain_struct *pstr_allpass_chain) { + LOOPIDX i, j; + WORD32 allpass_count = 0; + + for (i = 0; i < pstr_filter_cascade_t_domain->block_count; i++) { + ia_drc_eq_filter_element_struct *pstr_eq_filter_element = + &pstr_filter_cascade_t_domain->str_eq_filter_block[i].str_eq_filter_element[0]; + + if (pstr_filter_cascade_t_domain->str_eq_filter_block[i] + .str_matching_phase_filter_element_0.is_valid != 1) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG; + } else { + pstr_allpass_chain->str_matching_phase_filter[allpass_count] = + pstr_filter_cascade_t_domain->str_eq_filter_block[i] + .str_matching_phase_filter_element_0; + allpass_count++; + } + + for (j = 0; j < pstr_eq_filter_element->phase_alignment_filter_count; j++) { + if (pstr_eq_filter_element->str_phase_alignment_filter[j].is_valid != 1) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG; + } else { + pstr_allpass_chain->str_matching_phase_filter[allpass_count] = + pstr_eq_filter_element->str_phase_alignment_filter[j]; + allpass_count++; + } + } + } + pstr_allpass_chain->allpass_count = allpass_count; + + return IA_NO_ERROR; +} + +static VOID impd_drc_add_allpass_filter_chain( + ia_drc_allpass_chain_struct *pstr_allpass_chain, + ia_drc_filter_cascade_t_domain_struct *pstr_filter_cascade_t_domain) { + LOOPIDX idx; + + for (idx = 0; idx < pstr_allpass_chain->allpass_count; idx++) { + pstr_filter_cascade_t_domain + ->str_phase_alignment_filter[pstr_filter_cascade_t_domain->phase_alignment_filter_count + + idx] = pstr_allpass_chain->str_matching_phase_filter[idx]; + } + pstr_filter_cascade_t_domain->phase_alignment_filter_count += pstr_allpass_chain->allpass_count; +} + +static IA_ERRORCODE impd_drc_phase_align_cascade_group( + const WORD32 cascade_alignment_group_count, + ia_drc_cascade_alignment_group_struct *pstr_cascade_alignment_group, + ia_drc_filter_cascade_t_domain_struct *pstr_filter_cascade_t_domain, VOID *ptr_scratch, + WORD32 *scratch_used) { + IA_ERRORCODE err_code = IA_NO_ERROR; + LOOPIDX i, j, k; + WORD32 cascade_index; + ia_drc_allpass_chain_struct *pstr_allpass_chain = + (ia_drc_allpass_chain_struct *)((pUWORD8)(ptr_scratch)) + *scratch_used; + + for (i = 0; i < cascade_alignment_group_count; i++) { + for (j = 0; j < pstr_cascade_alignment_group[i].member_count; j++) { + cascade_index = pstr_cascade_alignment_group[i].member_index[j]; + + err_code = impd_drc_derive_allpass_chain(&pstr_filter_cascade_t_domain[cascade_index], + &pstr_allpass_chain[j]); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + pstr_allpass_chain[j].matches_cascade_index = cascade_index; + } + for (j = 0; j < pstr_cascade_alignment_group[i].member_count; j++) { + cascade_index = pstr_cascade_alignment_group[i].member_index[j]; + for (k = 0; k < pstr_cascade_alignment_group[i].member_count; k++) { + if (cascade_index != pstr_allpass_chain[k].matches_cascade_index) { + impd_drc_add_allpass_filter_chain(&pstr_allpass_chain[k], + &pstr_filter_cascade_t_domain[cascade_index]); + } + } + } + } + + return err_code; +} + +static VOID impd_drc_derive_matching_phase_filter_params( + const WORD32 config, FLOAT32 radius, FLOAT32 angle, + ia_drc_phase_alignment_filter_struct *pstr_phase_alignment_filter) { + LOOPIDX idx; + WORD32 section = pstr_phase_alignment_filter->section_count; + FLOAT32 z_real, z_imag, product; + ia_drc_filter_section_struct *pstr_filter_section = + &pstr_phase_alignment_filter->str_filter_section[section]; + + switch (config) { + case CONFIG_COMPLEX_POLE: + z_real = (FLOAT32)(radius * cos((FLOAT32)M_PI * angle)); + z_imag = (FLOAT32)(radius * sin((FLOAT32)M_PI * angle)); + product = z_real * z_real + z_imag * z_imag; + pstr_phase_alignment_filter->gain *= product; + pstr_filter_section->var_a1 = -2.0f * z_real; + pstr_filter_section->var_a2 = product; + pstr_filter_section->var_b1 = -2.0f * z_real / product; + pstr_filter_section->var_b2 = 1.0f / product; + pstr_phase_alignment_filter->section_count++; + break; + case CONFIG_REAL_POLE: + pstr_phase_alignment_filter->gain *= (-radius); + pstr_filter_section->var_a1 = -radius; + pstr_filter_section->var_a2 = 0.0f; + pstr_filter_section->var_b1 = -1.0f / radius; + pstr_filter_section->var_b2 = 0.0f; + pstr_phase_alignment_filter->section_count++; + break; + default: + break; + } + for (idx = 0; idx < MAX_EQ_CHANNEL_COUNT; idx++) { + pstr_filter_section->str_filter_section_state[idx].state_in_1 = 0.0f; + pstr_filter_section->str_filter_section_state[idx].state_out_1 = 0.0f; + pstr_filter_section->str_filter_section_state[idx].state_in_2 = 0.0f; + pstr_filter_section->str_filter_section_state[idx].state_out_2 = 0.0f; + } +} + +static VOID impd_drc_derive_matching_phase_filter_delay( + ia_drc_unique_td_filter_element_struct *pstr_filter_element, + ia_drc_phase_alignment_filter_struct *pstr_phase_alignment_filter) { + LOOPIDX i, j; + WORD32 delay = 0; + + if (pstr_filter_element->eq_filter_format == FILTER_ELEMENT_FORMAT_POLE_ZERO) { + if (pstr_filter_element->real_zero_radius_one_count == 0) { + delay = pstr_filter_element->real_zero_count + 2 * pstr_filter_element->generic_zero_count - + pstr_filter_element->real_pole_count - 2 * pstr_filter_element->complex_pole_count; + delay = MAX(0, delay); + pstr_phase_alignment_filter->is_valid = 1; + } + } + + pstr_phase_alignment_filter->str_audio_delay.delay = delay; + for (i = 0; i < MAX_EQ_CHANNEL_COUNT; i++) { + for (j = 0; j < delay; j++) { + pstr_phase_alignment_filter->str_audio_delay.state[i][j] = 0.0f; + } + } +} + +static VOID impd_drc_derive_matching_phase_filter( + ia_drc_unique_td_filter_element_struct *pstr_filter_element, WORD32 filter_element_index, + ia_drc_matching_phase_filter_struct *pstr_matching_phase_filter) { + LOOPIDX idx; + + memset(pstr_matching_phase_filter, 0, sizeof(ia_drc_matching_phase_filter_struct)); + pstr_matching_phase_filter->gain = 1.0f; + + if (pstr_filter_element->eq_filter_format == FILTER_ELEMENT_FORMAT_POLE_ZERO) { + for (idx = 0; idx < pstr_filter_element->real_pole_count; idx++) { + impd_drc_derive_matching_phase_filter_params(CONFIG_REAL_POLE, + pstr_filter_element->real_pole_radius[idx], + 0.0f, pstr_matching_phase_filter); + } + for (idx = 0; idx < pstr_filter_element->complex_pole_count; idx++) { + impd_drc_derive_matching_phase_filter_params( + CONFIG_COMPLEX_POLE, pstr_filter_element->complex_pole_radius[idx], + pstr_filter_element->complex_pole_angle[idx], pstr_matching_phase_filter); + } + } + impd_drc_derive_matching_phase_filter_delay(pstr_filter_element, pstr_matching_phase_filter); + + pstr_matching_phase_filter->matches_filter_count = 1; + pstr_matching_phase_filter->matches_filter[0] = filter_element_index; +} + +static VOID impd_drc_check_phase_filter_is_equal( + ia_drc_matching_phase_filter_struct *pstr_matching_phase_filter_1, + ia_drc_matching_phase_filter_struct *pstr_matching_phase_filter_2, WORD32 *is_equal) { + LOOPIDX idx; + + *is_equal = 1; + if (pstr_matching_phase_filter_1->section_count == + pstr_matching_phase_filter_2->section_count) { + for (idx = 0; idx < pstr_matching_phase_filter_1->section_count; idx++) { + if ((pstr_matching_phase_filter_1->str_filter_section[idx].var_a1 != + pstr_matching_phase_filter_2->str_filter_section[idx].var_a1) || + (pstr_matching_phase_filter_1->str_filter_section[idx].var_a2 != + pstr_matching_phase_filter_2->str_filter_section[idx].var_a2) || + (pstr_matching_phase_filter_1->str_filter_section[idx].var_b1 != + pstr_matching_phase_filter_2->str_filter_section[idx].var_b1) || + (pstr_matching_phase_filter_1->str_filter_section[idx].var_b2 != + pstr_matching_phase_filter_2->str_filter_section[idx].var_b2)) { + *is_equal = 0; + break; + } + } + } else { + *is_equal = 0; + } + + if (pstr_matching_phase_filter_1->str_audio_delay.delay != + pstr_matching_phase_filter_2->str_audio_delay.delay) { + *is_equal = 0; + } +} + +static IA_ERRORCODE impd_drc_add_phase_alignment_filter( + ia_drc_matching_phase_filter_struct *pstr_matching_phase_filter, + ia_drc_eq_filter_element_struct *pstr_eq_filter_element) { + if (pstr_matching_phase_filter->is_valid != 1) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG; + } else { + pstr_eq_filter_element + ->str_phase_alignment_filter[pstr_eq_filter_element->phase_alignment_filter_count] = + *pstr_matching_phase_filter; + pstr_eq_filter_element->phase_alignment_filter_count++; + } + + return IA_NO_ERROR; +} + +static IA_ERRORCODE impd_drc_derive_element_phase_alignment_filters( + ia_drc_matching_phase_filter_struct *pstr_matching_phase_filter, + ia_drc_eq_filter_block_struct *pstr_eq_filter_block, VOID *ptr_scratch, + WORD32 *scratch_used) { + IA_ERRORCODE err_code = IA_NO_ERROR; + LOOPIDX i, j, k; + WORD32 skip, is_equal; + WORD32 optimized_phase_filter_count; + WORD32 path_delay_min, path_delay, path_delay_new, path_delay_to_remove; + + ia_drc_matching_phase_filter_struct *pstr_matching_phase_filter_opt = + (ia_drc_matching_phase_filter_struct *)((pUWORD8)ptr_scratch) + *scratch_used; + ia_drc_eq_filter_element_struct *pstr_eq_filter_element; + + optimized_phase_filter_count = 0; + for (i = 0; i < pstr_eq_filter_block->element_count; i++) { + is_equal = 0; + for (j = 0; j < optimized_phase_filter_count; j++) { + impd_drc_check_phase_filter_is_equal(&pstr_matching_phase_filter[i], + &pstr_matching_phase_filter_opt[j], &is_equal); + if (is_equal == 1) { + break; + } + } + if (is_equal != 1) { + pstr_matching_phase_filter_opt[optimized_phase_filter_count] = + pstr_matching_phase_filter[i]; + optimized_phase_filter_count++; + } else { + pstr_matching_phase_filter_opt[j] + .matches_filter[pstr_matching_phase_filter_opt[j].matches_filter_count] = i; + pstr_matching_phase_filter_opt[j].matches_filter_count++; + } + } + + for (i = 0; i < pstr_eq_filter_block->element_count; i++) { + for (j = 0; j < optimized_phase_filter_count; j++) { + skip = 0; + for (k = 0; k < pstr_matching_phase_filter_opt[j].matches_filter_count; k++) { + if (pstr_matching_phase_filter_opt[j].matches_filter[k] == i) { + skip = 1; + break; + } + } + if (skip == 0) { + err_code = impd_drc_add_phase_alignment_filter( + &pstr_matching_phase_filter_opt[j], &pstr_eq_filter_block->str_eq_filter_element[i]); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + } + } + } + + path_delay_min = 100000; + for (i = 0; i < pstr_eq_filter_block->element_count; i++) { + pstr_eq_filter_element = &pstr_eq_filter_block->str_eq_filter_element[i]; + path_delay = 0; + for (k = 0; k < pstr_eq_filter_element->phase_alignment_filter_count; k++) { + path_delay += pstr_eq_filter_element->str_phase_alignment_filter[k].str_audio_delay.delay; + } + if (path_delay_min > path_delay) { + path_delay_min = path_delay; + } + } + if (path_delay_min > 0) { + for (i = 0; i < pstr_eq_filter_block->element_count; i++) { + pstr_eq_filter_element = &pstr_eq_filter_block->str_eq_filter_element[i]; + path_delay_to_remove = path_delay_min; + for (k = 0; k < pstr_eq_filter_element->phase_alignment_filter_count; k++) { + path_delay = pstr_eq_filter_element->str_phase_alignment_filter[k].str_audio_delay.delay; + path_delay_new = MAX(0, path_delay - path_delay_to_remove); + path_delay_to_remove -= path_delay - path_delay_new; + pstr_eq_filter_element->str_phase_alignment_filter[k].str_audio_delay.delay = + path_delay_new; + } + } + } + + return err_code; +} + +static IA_ERRORCODE impd_drc_convert_pole_zero_to_filter_params( + const WORD32 config, FLOAT32 radius, FLOAT32 angle, WORD32 *filter_param_count, + ia_drc_second_order_filter_params_struct *pstr_second_order_filter_params) { + FLOAT32 z_real, angle_1, angle_2; + FLOAT32 *ptr_coeff; + + switch (config) { + case CONFIG_REAL_POLE: { + pstr_second_order_filter_params[0].radius = radius; + ptr_coeff = pstr_second_order_filter_params[0].coeff; + ptr_coeff[0] = -2.0f * radius; + ptr_coeff[1] = radius * radius; + *filter_param_count = 1; + } break; + case CONFIG_COMPLEX_POLE: { + z_real = (FLOAT32)(radius * cos((FLOAT32)M_PI * angle)); + pstr_second_order_filter_params[0].radius = radius; + ptr_coeff = pstr_second_order_filter_params[0].coeff; + ptr_coeff[0] = -2.0f * z_real; + ptr_coeff[1] = radius * radius; + pstr_second_order_filter_params[1].radius = radius; + pstr_second_order_filter_params[1].coeff[0] = ptr_coeff[0]; + pstr_second_order_filter_params[1].coeff[1] = ptr_coeff[1]; + *filter_param_count = 2; + } break; + case CONFIG_REAL_ZERO_RADIUS_ONE: { + angle_1 = radius; + angle_2 = angle; + pstr_second_order_filter_params[0].radius = 1.0f; + ptr_coeff = pstr_second_order_filter_params[0].coeff; + + if (angle_1 != angle_2) { + ptr_coeff[0] = 0.0f; + ptr_coeff[1] = -1.0f; + } else if (angle_1 == 1.0f) { + ptr_coeff[0] = -2.0f; + ptr_coeff[1] = 1.0f; + } else { + ptr_coeff[0] = 2.0f; + ptr_coeff[1] = 1.0f; + } + *filter_param_count = 1; + } break; + case CONFIG_REAL_ZERO: { + pstr_second_order_filter_params[0].radius = radius; + if (fabs(radius) == 1.0f) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG; + } else { + ptr_coeff = pstr_second_order_filter_params[0].coeff; + ptr_coeff[0] = -(radius + 1.0f / radius); + ptr_coeff[1] = 1.0f; + } + *filter_param_count = 1; + } break; + case CONFIG_GENERIC_ZERO: { + z_real = (FLOAT32)(radius * cos((FLOAT32)M_PI * angle)); + pstr_second_order_filter_params[0].radius = radius; + ptr_coeff = pstr_second_order_filter_params[0].coeff; + ptr_coeff[0] = -2.0f * z_real; + ptr_coeff[1] = (FLOAT32)(radius * radius); + z_real = (FLOAT32)(cos((FLOAT32)M_PI * angle) / radius); + pstr_second_order_filter_params[1].radius = radius; + ptr_coeff = pstr_second_order_filter_params[1].coeff; + ptr_coeff[0] = -2.0f * z_real; + ptr_coeff[1] = 1.0f / (radius * radius); + *filter_param_count = 2; + } break; + default: + break; + } + + return IA_NO_ERROR; +} + +static VOID impd_drc_convert_fir_filter_params(const WORD32 fir_filter_order, + const WORD32 fir_symmetry, + FLOAT32 *fir_coefficient, + ia_drc_fir_filter_struct *pstr_fir_filter) { + LOOPIDX i, j; + FLOAT32 *ptr_coeff = pstr_fir_filter->coeff; + + pstr_fir_filter->coeff_count = fir_filter_order + 1; + for (i = 0; i < (fir_filter_order / 2 + 1); i++) { + ptr_coeff[i] = fir_coefficient[i]; + } + for (i = 0; i < (fir_filter_order + 1) / 2; i++) { + if (fir_symmetry != 1) { + ptr_coeff[fir_filter_order - i] = ptr_coeff[i]; + } else { + ptr_coeff[fir_filter_order - i] = -ptr_coeff[i]; + } + } + if ((fir_symmetry == 1) && ((fir_filter_order & 1) == 0)) { + ptr_coeff[fir_filter_order / 2] = 0.0f; + } + for (i = 0; i < MAX_EQ_CHANNEL_COUNT; i++) { + for (j = 0; j < (fir_filter_order + 1); j++) { + pstr_fir_filter->state[i][j] = 0.0f; + } + } +} + +static IA_ERRORCODE impd_drc_derive_pole_zero_filter_params( + ia_drc_unique_td_filter_element_struct *pstr_filter_element, + ia_drc_intermediate_filter_params_struct *pstr_intermediate_filter_params) { + IA_ERRORCODE err_code = IA_NO_ERROR; + LOOPIDX idx; + WORD32 param_index, filter_param_count; + ia_drc_second_order_filter_params_struct *pstr_second_order_filter_params_for_zeros; + ia_drc_second_order_filter_params_struct *pstr_second_order_filter_params_for_poles; + + pstr_intermediate_filter_params->filter_format = pstr_filter_element->eq_filter_format; + if (pstr_filter_element->eq_filter_format != FILTER_ELEMENT_FORMAT_POLE_ZERO) { + pstr_intermediate_filter_params->filter_param_count_for_zeros = 0; + pstr_intermediate_filter_params->filter_param_count_for_poles = 0; + + impd_drc_convert_fir_filter_params( + pstr_filter_element->fir_filter_order, pstr_filter_element->fir_symmetry, + pstr_filter_element->fir_coefficient, &pstr_intermediate_filter_params->str_fir_filter); + } else { + pstr_second_order_filter_params_for_zeros = + pstr_intermediate_filter_params->str_second_order_filter_params_for_zeros; + pstr_second_order_filter_params_for_poles = + pstr_intermediate_filter_params->str_second_order_filter_params_for_poles; + + param_index = 0; + for (idx = 0; idx < pstr_filter_element->real_zero_radius_one_count; idx += 2) { + err_code = impd_drc_convert_pole_zero_to_filter_params( + CONFIG_REAL_ZERO_RADIUS_ONE, pstr_filter_element->zero_sign[idx], + pstr_filter_element->zero_sign[idx + 1], &filter_param_count, + &(pstr_second_order_filter_params_for_zeros[param_index])); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + param_index += filter_param_count; + } + for (idx = 0; idx < pstr_filter_element->real_zero_count; idx++) { + err_code = impd_drc_convert_pole_zero_to_filter_params( + CONFIG_REAL_ZERO, pstr_filter_element->real_zero_radius[idx], 0.0f, &filter_param_count, + &(pstr_second_order_filter_params_for_zeros[param_index])); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + param_index += filter_param_count; + } + for (idx = 0; idx < pstr_filter_element->generic_zero_count; idx++) { + err_code = impd_drc_convert_pole_zero_to_filter_params( + CONFIG_GENERIC_ZERO, pstr_filter_element->generic_zero_radius[idx], + pstr_filter_element->generic_zero_angle[idx], &filter_param_count, + &(pstr_second_order_filter_params_for_zeros[param_index])); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + param_index += filter_param_count; + } + pstr_intermediate_filter_params->filter_param_count_for_zeros = param_index; + + param_index = 0; + for (idx = 0; idx < pstr_filter_element->real_pole_count; idx++) { + err_code = impd_drc_convert_pole_zero_to_filter_params( + CONFIG_REAL_POLE, pstr_filter_element->real_pole_radius[idx], 0.0f, &filter_param_count, + &(pstr_second_order_filter_params_for_poles[param_index])); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + param_index += filter_param_count; + } + for (idx = 0; idx < pstr_filter_element->complex_pole_count; idx++) { + err_code = impd_drc_convert_pole_zero_to_filter_params( + CONFIG_COMPLEX_POLE, pstr_filter_element->complex_pole_radius[idx], + pstr_filter_element->complex_pole_angle[idx], &filter_param_count, + &(pstr_second_order_filter_params_for_poles[param_index])); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + param_index += filter_param_count; + } + pstr_intermediate_filter_params->filter_param_count_for_poles = param_index; + } + + return err_code; +} + +static VOID impd_drc_derive_eq_filter_elements( + ia_drc_intermediate_filter_params_struct *pstr_intermediate_filter_params, + ia_drc_eq_filter_element_struct *pstr_eq_filter_element, pUWORD8 ptr_scratch) { + LOOPIDX idx, ch_idx; + WORD32 poles_index, zeros_index, pole_order = 0, section; + WORD32 coeff_count, coeff_idx; + WORD32 *ptr_poles_done = (WORD32 *)ptr_scratch; + WORD32 *ptr_zeros_done = + (WORD32 *)(ptr_scratch + + ((REAL_POLE_COUNT_MAX + COMPLEX_POLE_COUNT_MAX) * sizeof(ptr_poles_done[0]))); + FLOAT32 radius_max, radius_diff; + FLOAT32 temp_b1, temp_b2; + FLOAT32 *ptr_coeff; + + for (idx = 0; idx < (REAL_ZERO_COUNT_MAX + COMPLEX_ZERO_COUNT_MAX); idx++) { + ptr_zeros_done[idx] = 0; + } + for (idx = 0; idx < (REAL_POLE_COUNT_MAX + COMPLEX_POLE_COUNT_MAX); idx++) { + ptr_poles_done[idx] = 0; + } + section = 0; + do { + poles_index = -1; + radius_max = -1.0; + for (idx = 0; idx < pstr_intermediate_filter_params->filter_param_count_for_poles; idx++) { + if ((ptr_poles_done[idx] == 0) && (pstr_intermediate_filter_params->filter_format == 0)) { + if (radius_max < + fabs(pstr_intermediate_filter_params->str_second_order_filter_params_for_poles[idx] + .radius)) { + radius_max = (FLOAT32)fabs( + pstr_intermediate_filter_params->str_second_order_filter_params_for_poles[idx] + .radius); + poles_index = idx; + if (pstr_intermediate_filter_params->str_second_order_filter_params_for_poles[idx] + .coeff[1] == 0.0f) { + pole_order = 1; + } else { + pole_order = 2; + } + } + } + } + + if (poles_index >= 0) { + radius_diff = 10.0f; + zeros_index = -1; + for (idx = 0; idx < pstr_intermediate_filter_params->filter_param_count_for_zeros; idx++) { + if (ptr_zeros_done[idx] == 0 && pstr_intermediate_filter_params->filter_format == 0) { + if (pole_order == 2) { + if (pstr_intermediate_filter_params->str_second_order_filter_params_for_zeros[idx] + .coeff[1] != 0.0f) { + if (radius_diff > fabs(fabs(pstr_intermediate_filter_params + ->str_second_order_filter_params_for_zeros[idx] + .radius) - + radius_max)) { + radius_diff = + (FLOAT32)fabs(fabs(pstr_intermediate_filter_params + ->str_second_order_filter_params_for_zeros[idx] + .radius) - + radius_max); + zeros_index = idx; + } + } + } else { + if (pstr_intermediate_filter_params->str_second_order_filter_params_for_zeros[idx] + .coeff[1] == 0.0f) { + if (radius_diff > fabs(fabs(pstr_intermediate_filter_params + ->str_second_order_filter_params_for_zeros[idx] + .radius) - + radius_max)) { + radius_diff = + (FLOAT32)fabs(fabs(pstr_intermediate_filter_params + ->str_second_order_filter_params_for_zeros[idx] + .radius) - + radius_max); + zeros_index = idx; + } + } + } + } + } + + if (zeros_index == -1) { + for (idx = 0; idx < pstr_intermediate_filter_params->filter_param_count_for_zeros; + idx++) { + if (ptr_zeros_done[idx] == 0 && pstr_intermediate_filter_params->filter_format == 0) { + if (pole_order == 2) { + if (pstr_intermediate_filter_params->str_second_order_filter_params_for_zeros[idx] + .coeff[1] == 0.0f) { + if (radius_diff > fabs(fabs(pstr_intermediate_filter_params + ->str_second_order_filter_params_for_zeros[idx] + .radius) - + radius_max)) { + radius_diff = + (FLOAT32)fabs(fabs(pstr_intermediate_filter_params + ->str_second_order_filter_params_for_zeros[idx] + .radius) - + radius_max); + zeros_index = idx; + } + } + } else { + if (pstr_intermediate_filter_params->str_second_order_filter_params_for_zeros[idx] + .coeff[1] != 0.0f) { + if (radius_diff > fabs(fabs(pstr_intermediate_filter_params + ->str_second_order_filter_params_for_zeros[idx] + .radius) - + radius_max)) { + radius_diff = + (FLOAT32)fabs(fabs(pstr_intermediate_filter_params + ->str_second_order_filter_params_for_zeros[idx] + .radius) - + radius_max); + zeros_index = idx; + } + } + } + } + } + } + pstr_eq_filter_element->str_pole_zero_filter.str_filter_section[section].var_a1 = + pstr_intermediate_filter_params->str_second_order_filter_params_for_poles[poles_index] + .coeff[0]; + pstr_eq_filter_element->str_pole_zero_filter.str_filter_section[section].var_a2 = + pstr_intermediate_filter_params->str_second_order_filter_params_for_poles[poles_index] + .coeff[1]; + if (zeros_index < 0) { + pstr_eq_filter_element->str_pole_zero_filter.str_filter_section[section].var_b1 = 0.0f; + pstr_eq_filter_element->str_pole_zero_filter.str_filter_section[section].var_b2 = 0.0f; + pstr_eq_filter_element->str_pole_zero_filter.str_audio_delay.delay++; + } else { + pstr_eq_filter_element->str_pole_zero_filter.str_filter_section[section].var_b1 = + pstr_intermediate_filter_params->str_second_order_filter_params_for_zeros[zeros_index] + .coeff[0]; + pstr_eq_filter_element->str_pole_zero_filter.str_filter_section[section].var_b2 = + pstr_intermediate_filter_params->str_second_order_filter_params_for_zeros[zeros_index] + .coeff[1]; + } + for (ch_idx = 0; ch_idx < MAX_EQ_CHANNEL_COUNT; ch_idx++) { + pstr_eq_filter_element->str_pole_zero_filter.str_filter_section[section] + .str_filter_section_state[ch_idx] + .state_in_1 = 0.0f; + pstr_eq_filter_element->str_pole_zero_filter.str_filter_section[section] + .str_filter_section_state[ch_idx] + .state_in_2 = 0.0f; + pstr_eq_filter_element->str_pole_zero_filter.str_filter_section[section] + .str_filter_section_state[ch_idx] + .state_out_1 = 0.0f; + pstr_eq_filter_element->str_pole_zero_filter.str_filter_section[section] + .str_filter_section_state[ch_idx] + .state_out_2 = 0.0f; + } + if (zeros_index >= 0) { + ptr_zeros_done[zeros_index] = 1; + } + if (poles_index >= 0) { + ptr_poles_done[poles_index] = 1; + } + section++; + } + } while (poles_index >= 0); + + pstr_eq_filter_element->str_pole_zero_filter.section_count = section; + + coeff_count = 1; + ptr_coeff = pstr_eq_filter_element->str_pole_zero_filter.str_fir_filter.coeff; + ptr_coeff[0] = 1.0f; + for (idx = 0; idx < pstr_intermediate_filter_params->filter_param_count_for_zeros; idx++) { + if (ptr_zeros_done[idx] == 0 && pstr_intermediate_filter_params->filter_format == 0) { + temp_b1 = + pstr_intermediate_filter_params->str_second_order_filter_params_for_zeros[idx].coeff[0]; + temp_b2 = + pstr_intermediate_filter_params->str_second_order_filter_params_for_zeros[idx].coeff[1]; + + coeff_count += 2; + coeff_idx = coeff_count - 1; + ptr_coeff[coeff_idx] = temp_b2 * ptr_coeff[coeff_idx - 2]; + coeff_idx--; + if (coeff_idx > 1) { + ptr_coeff[coeff_idx] = + temp_b1 * ptr_coeff[coeff_idx - 1] + temp_b2 * ptr_coeff[coeff_idx - 2]; + coeff_idx--; + for (; coeff_idx > 1; coeff_idx--) { + ptr_coeff[coeff_idx] += + temp_b1 * ptr_coeff[coeff_idx - 1] + temp_b2 * ptr_coeff[coeff_idx - 2]; + } + ptr_coeff[1] += temp_b1 * ptr_coeff[0]; + } else { + ptr_coeff[1] = temp_b1 * ptr_coeff[0]; + } + } + ptr_zeros_done[idx] = 1; + } + if (coeff_count > 1) { + pstr_eq_filter_element->str_pole_zero_filter.fir_coeffs_present = 1; + pstr_eq_filter_element->str_pole_zero_filter.str_fir_filter.coeff_count = coeff_count; + } else { + pstr_eq_filter_element->str_pole_zero_filter.fir_coeffs_present = 0; + pstr_eq_filter_element->str_pole_zero_filter.str_fir_filter.coeff_count = 0; + } +} + +static IA_ERRORCODE impd_drc_derive_filter_block( + ia_drc_unique_td_filter_element_struct *pstr_unique_td_filter_element, + ia_drc_filter_block_struct *pstr_filter_block, + ia_drc_eq_filter_block_struct *pstr_eq_filter_block, VOID *ptr_scratch, + WORD32 *scratch_used) { + IA_ERRORCODE err_code = IA_NO_ERROR; + LOOPIDX i, j; + WORD32 filter_index; + WORD32 temp_scratch_used = *scratch_used; + ia_drc_intermediate_filter_params_struct str_intermediate_filter_params; + ia_drc_eq_filter_element_struct *pstr_eq_filter_element; + ia_drc_filter_element_struct *pstr_filter_element; + ia_drc_matching_phase_filter_struct *pstr_matching_phase_filter = + (ia_drc_matching_phase_filter_struct *)((pUWORD8)(ptr_scratch)) + temp_scratch_used; + + temp_scratch_used += sizeof(ia_drc_matching_phase_filter_struct) * FILTER_ELEMENT_COUNT_MAX; + + for (i = 0; i < pstr_filter_block->filter_element_count; i++) { + if ((pstr_unique_td_filter_element[pstr_filter_block->filter_element[i].filter_element_index] + .eq_filter_format == FILTER_ELEMENT_FORMAT_FIR) && + (pstr_filter_block->filter_element_count > 1)) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG; + } + } + for (i = 0; i < pstr_filter_block->filter_element_count; i++) { + pstr_filter_element = &pstr_filter_block->filter_element[i]; + filter_index = pstr_filter_element->filter_element_index; + pstr_eq_filter_element = &pstr_eq_filter_block->str_eq_filter_element[i]; + + if (pstr_unique_td_filter_element[filter_index].eq_filter_format == + FILTER_ELEMENT_FORMAT_POLE_ZERO) { + err_code = impd_drc_derive_pole_zero_filter_params( + &(pstr_unique_td_filter_element[filter_index]), &str_intermediate_filter_params); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + + impd_drc_derive_eq_filter_elements(&str_intermediate_filter_params, pstr_eq_filter_element, + (pUWORD8)(ptr_scratch) + temp_scratch_used); + pstr_eq_filter_element->format = FILTER_ELEMENT_FORMAT_POLE_ZERO; + } else { + impd_drc_convert_fir_filter_params( + pstr_unique_td_filter_element[filter_index].fir_filter_order, + pstr_unique_td_filter_element[filter_index].fir_symmetry, + pstr_unique_td_filter_element[filter_index].fir_coefficient, + &pstr_eq_filter_element->str_fir_filter); + pstr_eq_filter_element->format = FILTER_ELEMENT_FORMAT_FIR; + } + if (pstr_filter_element->filter_element_gain_present != 1) { + pstr_eq_filter_element->element_gain_linear = 1.0f; + } else { + pstr_eq_filter_element->element_gain_linear = + (FLOAT32)pow(10.0f, 0.05f * pstr_filter_element->filter_element_gain); + } + for (j = 0; j < pstr_unique_td_filter_element[filter_index].real_zero_count; j++) { + if (pstr_unique_td_filter_element[filter_index].real_zero_radius[j] > 0.0f) { + pstr_eq_filter_element->element_gain_linear = + -pstr_eq_filter_element->element_gain_linear; + } + } + impd_drc_derive_matching_phase_filter(&(pstr_unique_td_filter_element[filter_index]), i, + &pstr_matching_phase_filter[i]); + } + pstr_eq_filter_block->str_matching_phase_filter_element_0 = pstr_matching_phase_filter[0]; + pstr_eq_filter_block->element_count = pstr_filter_block->filter_element_count; + + err_code = impd_drc_derive_element_phase_alignment_filters( + pstr_matching_phase_filter, pstr_eq_filter_block, ptr_scratch, &temp_scratch_used); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + + return err_code; +} + +static IA_ERRORCODE impd_drc_derive_cascade_phase_alignment_filters( + ia_drc_td_filter_cascade_struct *pstr_td_filter_cascade, const WORD32 channel_group_count, + ia_drc_filter_cascade_t_domain_struct *pstr_filter_cascade_t_domain, VOID *ptr_scratch, + WORD32 *scratch_used) { + IA_ERRORCODE err_code = IA_NO_ERROR; + WORD32 cascade_alignment_group_count = 0; + ia_drc_cascade_alignment_group_struct *pstr_cascade_alignment_group = + (ia_drc_cascade_alignment_group_struct *)ptr_scratch; + *scratch_used += + sizeof(ia_drc_cascade_alignment_group_struct) * (EQ_MAX_CHANNEL_GROUP_COUNT / 2); + + impd_drc_derive_cascade_alignment_groups( + channel_group_count, pstr_td_filter_cascade->eq_phase_alignment_present, + (const WORD32(*)[EQ_MAX_CHANNEL_GROUP_COUNT])pstr_td_filter_cascade->eq_phase_alignment, + &cascade_alignment_group_count, pstr_cascade_alignment_group); + + if (cascade_alignment_group_count > 0) { + err_code = impd_drc_phase_align_cascade_group( + cascade_alignment_group_count, pstr_cascade_alignment_group, pstr_filter_cascade_t_domain, + ptr_scratch, scratch_used); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + } + + return err_code; +} + +static IA_ERRORCODE impd_drc_derive_filter_cascade( + ia_drc_unique_td_filter_element_struct *pstr_unique_td_filter_element, + ia_drc_filter_block_struct *pstr_filter_block, + ia_drc_td_filter_cascade_struct *pstr_td_filter_cascade, WORD32 channel_group_count, + ia_drc_filter_cascade_t_domain_struct *pstr_filter_cascade_t_domain, VOID *ptr_scratch, + WORD32 *scratch_used) { + IA_ERRORCODE err_code = IA_NO_ERROR; + LOOPIDX i, j; + + for (i = 0; i < channel_group_count; i++) { + for (j = 0; j < pstr_td_filter_cascade->str_filter_block_refs[i].filter_block_count; j++) { + err_code = impd_drc_derive_filter_block( + pstr_unique_td_filter_element, + &(pstr_filter_block[pstr_td_filter_cascade->str_filter_block_refs[i] + .filter_block_index[j]]), + &(pstr_filter_cascade_t_domain[i].str_eq_filter_block[j]), ptr_scratch, scratch_used); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + } + pstr_filter_cascade_t_domain[i].cascade_gain_linear = + (FLOAT32)pow(10.0f, 0.05f * pstr_td_filter_cascade->eq_cascade_gain[i]); + pstr_filter_cascade_t_domain[i].block_count = j; + } + + err_code = impd_drc_derive_cascade_phase_alignment_filters( + pstr_td_filter_cascade, channel_group_count, pstr_filter_cascade_t_domain, ptr_scratch, + scratch_used); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + + return err_code; +} + +static VOID impd_drc_derive_subband_eq( + ia_drc_eq_subband_gain_vector_struct *pstr_eq_subband_gain_vector, + const WORD32 eq_subband_gain_count, ia_drc_subband_filter_struct *pstr_subband_filter) { + LOOPIDX idx; + + for (idx = 0; idx < eq_subband_gain_count; idx++) { + pstr_subband_filter->subband_coeff[idx] = + (FLOAT32)pstr_eq_subband_gain_vector->eq_subband_gain[idx]; + } + pstr_subband_filter->coeff_count = eq_subband_gain_count; +} + +static FLOAT32 impd_drc_decode_eq_node_freq(const WORD32 eq_node_freq_index) { + FLOAT32 eq_node_frequency; + + eq_node_frequency = + (FLOAT32)(pow(STEP_RATIO_F_LOW, 1.0f + eq_node_freq_index * STEP_RATIO_COMPUTED)); + + return eq_node_frequency; +} + +static FLOAT32 impd_drc_warp_freq_delta(const FLOAT32 f_subband, const FLOAT32 node_frequency_0, + const WORD32 eq_node_freq_index) { + FLOAT32 wraped_delta_frequency; + + wraped_delta_frequency = + (FLOAT32)((log10(f_subband) / log10(node_frequency_0) - 1.0f) / STEP_RATIO_COMPUTED - + (FLOAT32)eq_node_freq_index); + + return wraped_delta_frequency; +} + +static VOID impd_drc_interpolate_eq_gain(const WORD32 band_step, const FLOAT32 eq_gain_0, + const FLOAT32 eq_gain_1, const FLOAT32 eq_slope_0, + const FLOAT32 eq_slope_1, const FLOAT32 wrap_delta_freq, + FLOAT32 *interpolated_gain) { + FLOAT32 k1, k2, val_a, val_b; + FLOAT32 nodes_per_octave_count = 3.128f; + FLOAT32 gain_left = eq_gain_0; + FLOAT32 gain_right = eq_gain_1; + FLOAT32 slope_left = eq_slope_0 / nodes_per_octave_count; + FLOAT32 slope_right = eq_slope_1 / nodes_per_octave_count; + FLOAT32 band_step_inv = (FLOAT32)(1.0 / (FLOAT32)band_step); + FLOAT32 band_step_inv_square = band_step_inv * band_step_inv; + + k1 = (gain_right - gain_left) * band_step_inv_square; + k2 = slope_right + slope_left; + val_a = (FLOAT32)(band_step_inv * (band_step_inv * k2 - 2.0 * k1)); + val_b = (FLOAT32)(3.0 * k1 - band_step_inv * (k2 + slope_left)); + + *interpolated_gain = + (((val_a * wrap_delta_freq + val_b) * wrap_delta_freq + slope_left) * wrap_delta_freq) + + gain_left; +} + +static IA_ERRORCODE impd_drc_interpolate_subband_spline( + ia_drc_eq_subband_gain_spline_struct *pstr_eq_subband_gain_spline, + const WORD32 eq_subband_gain_count, const WORD32 eq_subband_gain_format, + const FLOAT32 audio_sample_rate, ia_drc_subband_filter_struct *pstr_subband_filter, + VOID *ptr_scratch) { + IA_ERRORCODE err_code = IA_NO_ERROR; + LOOPIDX i, j; + WORD32 eq_node_freq_index[32] = {0}; + WORD32 n_eq_nodes = pstr_eq_subband_gain_spline->n_eq_nodes; + WORD32 eq_node_count_max = 33; + WORD32 eq_node_index_max = eq_node_count_max - 1; + WORD32 *ptr_eq_freq_delta = pstr_eq_subband_gain_spline->eq_freq_delta; + FLOAT32 eq_gain[32] = {0}, eq_node_freq[32] = {0}; + FLOAT32 freq_subband, warped_delta_freq, g_eq_subband_db; + FLOAT32 eq_gain_initial = pstr_eq_subband_gain_spline->eq_gain_initial; + FLOAT32 *ptr_subband_center_freq = (FLOAT32 *)ptr_scratch; + FLOAT32 *ptr_eq_slope = pstr_eq_subband_gain_spline->eq_slope; + FLOAT32 *ptr_eq_gain_delta = pstr_eq_subband_gain_spline->eq_gain_delta; + FLOAT32 *ptr_subband_coeff = pstr_subband_filter->subband_coeff; + + eq_gain[0] = eq_gain_initial; + eq_node_freq_index[0] = 0; + eq_node_freq[0] = impd_drc_decode_eq_node_freq(eq_node_freq_index[0]); + for (i = 1; i < n_eq_nodes; i++) { + eq_gain[i] = eq_gain[i - 1] + ptr_eq_gain_delta[i]; + eq_node_freq_index[i] = eq_node_freq_index[i - 1] + ptr_eq_freq_delta[i]; + eq_node_freq[i] = impd_drc_decode_eq_node_freq(eq_node_freq_index[i]); + } + if ((eq_node_freq[n_eq_nodes - 1] < audio_sample_rate * 0.5f) && + (eq_node_freq_index[n_eq_nodes - 1] < eq_node_index_max)) { + ptr_eq_slope[n_eq_nodes] = 0; + eq_gain[n_eq_nodes] = eq_gain[n_eq_nodes - 1]; + ptr_eq_freq_delta[n_eq_nodes] = eq_node_index_max - eq_node_freq_index[n_eq_nodes - 1]; + eq_node_freq_index[n_eq_nodes] = eq_node_index_max; + eq_node_freq[n_eq_nodes] = impd_drc_decode_eq_node_freq(eq_node_freq_index[n_eq_nodes]); + n_eq_nodes += 1; + } + + err_code = impd_drc_derive_subband_center_freq(eq_subband_gain_count, eq_subband_gain_format, + audio_sample_rate, ptr_subband_center_freq); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + + for (i = 0; i < n_eq_nodes - 1; i++) { + for (j = 0; j < eq_subband_gain_count; j++) { + freq_subband = MAX(ptr_subband_center_freq[j], eq_node_freq[0]); + freq_subband = MIN(freq_subband, eq_node_freq[n_eq_nodes - 1]); + if ((freq_subband >= eq_node_freq[i]) && (freq_subband <= eq_node_freq[i + 1])) { + warped_delta_freq = + impd_drc_warp_freq_delta(freq_subband, eq_node_freq[0], eq_node_freq_index[i]); + impd_drc_interpolate_eq_gain(ptr_eq_freq_delta[i + 1], eq_gain[i], eq_gain[i + 1], + ptr_eq_slope[i], ptr_eq_slope[i + 1], warped_delta_freq, + &g_eq_subband_db); + + ptr_subband_coeff[j] = (FLOAT32)pow(2.0, (FLOAT32)(g_eq_subband_db / 6.0f)); + } + } + } + pstr_subband_filter->coeff_count = eq_subband_gain_count; + + return err_code; +} + +static IA_ERRORCODE impd_drc_derive_subband_gains( + ia_drc_eq_coefficients_struct *pstr_eq_coefficients, const WORD32 eq_channel_group_count, + const WORD32 *subband_gains_index, const FLOAT32 audio_sample_rate, + const WORD32 eq_frame_size_subband, ia_drc_subband_filter_struct *pstr_subband_filter, + VOID *ptr_scratch) { + IA_ERRORCODE err_code = IA_NO_ERROR; + LOOPIDX idx; + + for (idx = 0; idx < eq_channel_group_count; idx++) { + if (pstr_eq_coefficients->eq_subband_gain_representation != 1) { + impd_drc_derive_subband_eq( + &(pstr_eq_coefficients->str_eq_subband_gain_vector[subband_gains_index[idx]]), + pstr_eq_coefficients->eq_subband_gain_count, &(pstr_subband_filter[idx])); + } else { + err_code = impd_drc_interpolate_subband_spline( + &(pstr_eq_coefficients->str_eq_subband_gain_spline[subband_gains_index[idx]]), + pstr_eq_coefficients->eq_subband_gain_count, + pstr_eq_coefficients->eq_subband_gain_format, audio_sample_rate, + &(pstr_subband_filter[idx]), ptr_scratch); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + } + pstr_subband_filter[idx].eq_frame_size_subband = eq_frame_size_subband; + } + + return err_code; +} + +IA_ERRORCODE impd_drc_get_eq_complexity(ia_drc_eq_set_struct *pstr_eq_set, + WORD32 *eq_complexity_level) { + LOOPIDX idx_c, idx_b, i, j; + WORD32 group; + WORD32 fir_order_complexity = 0; + WORD32 zero_pole_pair_count_complexity = 0; + WORD32 subband_filter_complexity = 0; + FLOAT32 complexity; + ia_drc_filter_cascade_t_domain_struct *pstr_filter_cascade_t_domain; + ia_drc_eq_filter_block_struct *pstr_eq_filter_block; + ia_drc_eq_filter_element_struct *pstr_eq_filter_element; + + for (idx_c = 0; idx_c < pstr_eq_set->audio_channel_count; idx_c++) { + group = pstr_eq_set->eq_channel_group_for_channel[idx_c]; + if (group >= 0) { + switch (pstr_eq_set->domain) { + case EQ_FILTER_DOMAIN_TIME: { + pstr_filter_cascade_t_domain = &pstr_eq_set->str_filter_cascade_t_domain[group]; + for (idx_b = 0; idx_b < pstr_filter_cascade_t_domain->block_count; idx_b++) { + pstr_eq_filter_block = &pstr_filter_cascade_t_domain->str_eq_filter_block[idx_b]; + for (i = 0; i < pstr_eq_filter_block->element_count; i++) { + pstr_eq_filter_element = &pstr_eq_filter_block->str_eq_filter_element[i]; + switch (pstr_eq_filter_element->format) { + case FILTER_ELEMENT_FORMAT_POLE_ZERO: + zero_pole_pair_count_complexity += + pstr_eq_filter_element->str_pole_zero_filter.section_count * 2; + if (pstr_eq_filter_element->str_pole_zero_filter.fir_coeffs_present) { + fir_order_complexity += + pstr_eq_filter_element->str_pole_zero_filter.str_fir_filter.coeff_count - + 1; + } + break; + case FILTER_ELEMENT_FORMAT_FIR: + fir_order_complexity += pstr_eq_filter_element->str_fir_filter.coeff_count - 1; + break; + default: + break; + } + for (j = 0; j < pstr_eq_filter_element->phase_alignment_filter_count; j++) { + zero_pole_pair_count_complexity += + pstr_eq_filter_element->str_phase_alignment_filter[j].section_count * 2; + } + } + } + for (idx_b = 0; idx_b < pstr_filter_cascade_t_domain->phase_alignment_filter_count; + idx_b++) { + zero_pole_pair_count_complexity += + pstr_filter_cascade_t_domain->str_phase_alignment_filter[idx_b].section_count * 2; + } + } break; + case EQ_FILTER_DOMAIN_SUBBAND: + subband_filter_complexity++; + break; + case EQ_FILTER_DOMAIN_NONE: + default: + break; + } + } + } + complexity = COMPLEXITY_W_SUBBAND_EQ * subband_filter_complexity; + complexity += COMPLEXITY_W_FIR * fir_order_complexity; + complexity += COMPLEXITY_W_IIR * zero_pole_pair_count_complexity; + complexity = (FLOAT32)(log10(complexity / pstr_eq_set->audio_channel_count) / log10(2.0f)); + *eq_complexity_level = (WORD32)MAX(0, ceil(complexity)); + if (*eq_complexity_level > EQ_COMPLEXITY_LEVEL_MAX) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG; + } + + return IA_NO_ERROR; +} + +IA_ERRORCODE impd_drc_derive_eq_set(ia_drc_eq_coefficients_struct *pstr_eq_coefficients, + ia_drc_eq_instructions_struct *pstr_eq_instructions, + const FLOAT32 audio_sample_rate, const WORD32 drc_frame_size, + const WORD32 sub_band_domain_mode, + ia_drc_eq_set_struct *pstr_eq_set, VOID *ptr_scratch, + WORD32 *scratch_used) { + IA_ERRORCODE err_code = IA_NO_ERROR; + LOOPIDX idx; + WORD32 eq_frame_size_subband; + + pstr_eq_set->domain = EQ_FILTER_DOMAIN_NONE; + + if (sub_band_domain_mode != SUBBAND_DOMAIN_MODE_OFF) { + switch (sub_band_domain_mode) { + case SUBBAND_DOMAIN_MODE_STFT256: + if (pstr_eq_coefficients->eq_subband_gain_count != STFT256_AUDIO_CODEC_SUBBAND_COUNT) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG; + } + eq_frame_size_subband = drc_frame_size / STFT256_AUDIO_CODEC_SUBBAND_DOWNSAMPLING_FACTOR; + break; + case SUBBAND_DOMAIN_MODE_QMF71: + if (pstr_eq_coefficients->eq_subband_gain_count != QMF71_AUDIO_CODEC_SUBBAND_COUNT) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG; + } + eq_frame_size_subband = drc_frame_size / QMF71_AUDIO_CODEC_SUBBAND_DOWNSAMPLING_FACTOR; + break; + case SUBBAND_DOMAIN_MODE_QMF64: + if (pstr_eq_coefficients->eq_subband_gain_count != QMF64_AUDIO_CODEC_SUBBAND_COUNT) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG; + } + eq_frame_size_subband = drc_frame_size / QMF64_AUDIO_CODEC_SUBBAND_DOWNSAMPLING_FACTOR; + break; + default: + return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG; + break; + } + if (pstr_eq_instructions->subband_gains_present == 1) { + err_code = impd_drc_derive_subband_gains( + pstr_eq_coefficients, pstr_eq_instructions->eq_channel_group_count, + pstr_eq_instructions->subband_gains_index, audio_sample_rate, eq_frame_size_subband, + pstr_eq_set->str_subband_filter, ptr_scratch); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + } else { + if (pstr_eq_instructions->td_filter_cascade_present == 1) { + err_code = impd_drc_derive_subband_gains_from_td_cascade( + pstr_eq_coefficients->str_unique_td_filter_element, + pstr_eq_coefficients->str_filter_block, &pstr_eq_instructions->str_td_filter_cascade, + pstr_eq_coefficients->eq_subband_gain_format, + pstr_eq_instructions->eq_channel_group_count, audio_sample_rate, + eq_frame_size_subband, pstr_eq_set->str_subband_filter, ptr_scratch); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + } else { + err_code = IA_EXHEAACE_CONFIG_NONFATAL_DRC_MISSING_CONFIG; + } + } + pstr_eq_set->domain |= EQ_FILTER_DOMAIN_SUBBAND; + } else { + if (pstr_eq_instructions->td_filter_cascade_present == 1) { + err_code = impd_drc_derive_filter_cascade( + pstr_eq_coefficients->str_unique_td_filter_element, + pstr_eq_coefficients->str_filter_block, &pstr_eq_instructions->str_td_filter_cascade, + pstr_eq_instructions->eq_channel_group_count, pstr_eq_set->str_filter_cascade_t_domain, + ptr_scratch, scratch_used); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + } + pstr_eq_set->domain |= EQ_FILTER_DOMAIN_TIME; + } + + pstr_eq_set->audio_channel_count = pstr_eq_instructions->eq_channel_count; + pstr_eq_set->eq_channel_group_count = pstr_eq_instructions->eq_channel_group_count; + + for (idx = 0; idx < pstr_eq_instructions->eq_channel_count; idx++) { + pstr_eq_set->eq_channel_group_for_channel[idx] = + pstr_eq_instructions->eq_channel_group_for_channel[idx]; + } + + return err_code; +} diff --git a/encoder/drc_src/impd_drc_uni_drc_eq.h b/encoder/drc_src/impd_drc_uni_drc_eq.h new file mode 100644 index 0000000..531273e --- /dev/null +++ b/encoder/drc_src/impd_drc_uni_drc_eq.h @@ -0,0 +1,172 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +#define MAX_EQ_CHANNEL_COUNT (8) +#define MAX_EQ_AUDIO_DELAY (1024) +#define MAX_EQ_FIR_FILTER_SIZE (128) +#define MAX_EQ_SUBBAND_COUNT (256) +#define MAX_EQ_INTERMEDIATE_2ND_ORDER_PARAMS_COUNT (32) +#define MAX_EQ_FILTER_SECTION_COUNT (8) +#define MAX_EQ_FILTER_ELEMENT_COUNT (4) +#define MAX_MATCHING_PHASE_FILTER_COUNT (32) + +#define EQ_FILTER_DOMAIN_NONE 0 +#define EQ_FILTER_DOMAIN_TIME (1) +#define EQ_FILTER_DOMAIN_SUBBAND (2) + +#define CONFIG_REAL_POLE (0) +#define CONFIG_COMPLEX_POLE (1) +#define CONFIG_REAL_ZERO_RADIUS_ONE (2) +#define CONFIG_REAL_ZERO (3) +#define CONFIG_GENERIC_ZERO (4) + +#define STEP_RATIO_F_LOW (20.0f) + +#define FILTER_ELEMENT_FORMAT_POLE_ZERO (0) +#define FILTER_ELEMENT_FORMAT_FIR (1) + +#ifndef M_PI +#define M_PI (3.14159265358979323846) +#endif + +#define STEP_RATIO_COMPUTED (0.0739601776f) + +typedef struct { + WORD32 delay; + FLOAT32 state[MAX_EQ_CHANNEL_COUNT][MAX_EQ_AUDIO_DELAY]; +} ia_drc_audio_delay_struct; + +typedef struct { + FLOAT32 radius; + FLOAT32 coeff[2]; +} ia_drc_second_order_filter_params_struct; + +typedef struct { + WORD32 coeff_count; + FLOAT32 coeff[MAX_EQ_FIR_FILTER_SIZE]; + FLOAT32 state[MAX_EQ_CHANNEL_COUNT][MAX_EQ_FIR_FILTER_SIZE]; +} ia_drc_fir_filter_struct; + +typedef struct { + WORD32 eq_frame_size_subband; + WORD32 coeff_count; + FLOAT32 subband_coeff[MAX_EQ_SUBBAND_COUNT]; +} ia_drc_subband_filter_struct; + +typedef struct { + WORD32 filter_format; + WORD32 filter_param_count_for_zeros; + ia_drc_second_order_filter_params_struct + str_second_order_filter_params_for_zeros[MAX_EQ_INTERMEDIATE_2ND_ORDER_PARAMS_COUNT]; + WORD32 filter_param_count_for_poles; + ia_drc_second_order_filter_params_struct + str_second_order_filter_params_for_poles[MAX_EQ_INTERMEDIATE_2ND_ORDER_PARAMS_COUNT]; + ia_drc_fir_filter_struct str_fir_filter; +} ia_drc_intermediate_filter_params_struct; + +typedef struct { + FLOAT32 state_in_1; + FLOAT32 state_in_2; + FLOAT32 state_out_1; + FLOAT32 state_out_2; +} ia_drc_filter_section_state_struct; + +typedef struct { + FLOAT32 var_a1; + FLOAT32 var_a2; + FLOAT32 var_b1; + FLOAT32 var_b2; + ia_drc_filter_section_state_struct str_filter_section_state[MAX_EQ_CHANNEL_COUNT]; +} ia_drc_filter_section_struct; + +typedef struct { + WORD32 member_count; + WORD32 member_index[EQ_MAX_CHANNEL_GROUP_COUNT]; +} ia_drc_cascade_alignment_group_struct; + +typedef struct { + WORD32 is_valid; + WORD32 matches_filter_count; + WORD32 matches_filter[MAX_EQ_FILTER_SECTION_COUNT]; + FLOAT32 gain; + WORD32 section_count; + ia_drc_filter_section_struct str_filter_section[MAX_EQ_FILTER_SECTION_COUNT]; + ia_drc_audio_delay_struct str_audio_delay; +} ia_drc_phase_alignment_filter_struct; + +typedef ia_drc_phase_alignment_filter_struct ia_drc_matching_phase_filter_struct; + +typedef struct { + WORD32 matches_cascade_index; + WORD32 allpass_count; + ia_drc_matching_phase_filter_struct str_matching_phase_filter[MAX_MATCHING_PHASE_FILTER_COUNT]; +} ia_drc_allpass_chain_struct; + +typedef struct { + WORD32 section_count; + ia_drc_filter_section_struct str_filter_section[MAX_EQ_FILTER_SECTION_COUNT]; + WORD32 fir_coeffs_present; + ia_drc_fir_filter_struct str_fir_filter; + ia_drc_audio_delay_struct str_audio_delay; +} ia_drc_pole_zero_filter_struct; + +typedef struct { + FLOAT32 element_gain_linear; + WORD32 format; + ia_drc_pole_zero_filter_struct str_pole_zero_filter; + ia_drc_fir_filter_struct str_fir_filter; + WORD32 phase_alignment_filter_count; + ia_drc_phase_alignment_filter_struct str_phase_alignment_filter[MAX_EQ_FILTER_ELEMENT_COUNT]; +} ia_drc_eq_filter_element_struct; + +typedef struct { + WORD32 element_count; + ia_drc_eq_filter_element_struct str_eq_filter_element[MAX_EQ_FILTER_ELEMENT_COUNT]; + ia_drc_matching_phase_filter_struct str_matching_phase_filter_element_0; +} ia_drc_eq_filter_block_struct; + +typedef struct { + FLOAT32 cascade_gain_linear; + WORD32 block_count; + ia_drc_eq_filter_block_struct str_eq_filter_block[EQ_FILTER_BLOCK_COUNT_MAX]; + WORD32 phase_alignment_filter_count; + ia_drc_phase_alignment_filter_struct + str_phase_alignment_filter[EQ_FILTER_BLOCK_COUNT_MAX * EQ_FILTER_BLOCK_COUNT_MAX]; +} ia_drc_filter_cascade_t_domain_struct; + +typedef struct { + WORD32 domain; + WORD32 audio_channel_count; + WORD32 eq_channel_group_count; + WORD32 eq_channel_group_for_channel[MAX_EQ_CHANNEL_COUNT]; + ia_drc_filter_cascade_t_domain_struct str_filter_cascade_t_domain[EQ_MAX_CHANNEL_GROUP_COUNT]; + ia_drc_subband_filter_struct str_subband_filter[EQ_MAX_CHANNEL_GROUP_COUNT]; +} ia_drc_eq_set_struct; + +IA_ERRORCODE impd_drc_derive_eq_set(ia_drc_eq_coefficients_struct *pstr_eq_coefficients, + ia_drc_eq_instructions_struct *pstr_eq_instructions, + const FLOAT32 audio_sample_rate, const WORD32 drc_frame_size, + const WORD32 sub_band_domain_mode, + ia_drc_eq_set_struct *pstr_eq_set, VOID *ptr_scratch, + WORD32 *scratch_used); + +IA_ERRORCODE impd_drc_get_eq_complexity(ia_drc_eq_set_struct *pstr_eq_set, + WORD32 *eq_complexity_level); diff --git a/encoder/drc_src/impd_drc_uni_drc_filter_bank.c b/encoder/drc_src/impd_drc_uni_drc_filter_bank.c new file mode 100644 index 0000000..a506584 --- /dev/null +++ b/encoder/drc_src/impd_drc_uni_drc_filter_bank.c @@ -0,0 +1,184 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include "ixheaac_type_def.h" +#include "ixheaac_error_standards.h" +#include "ixheaace_error_codes.h" + +#include "iusace_cnst.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_uni_drc_filter_bank.h" + +static IA_ERRORCODE impd_drc_filter_bank_complexity( + const WORD32 num_bands, ia_drc_filter_bank_struct *pstr_drc_filter_bank) { + pstr_drc_filter_bank->complexity = 0; + pstr_drc_filter_bank->num_bands = num_bands; + switch (num_bands) { + case 1: + break; + case 2: + pstr_drc_filter_bank->complexity = 8; + break; + case 3: + pstr_drc_filter_bank->complexity = 18; + break; + case 4: + pstr_drc_filter_bank->complexity = 28; + break; + default: + return IA_EXHEAACE_CONFIG_FATAL_DRC_PARAM_OUT_OF_RANGE; + break; + } + + return IA_NO_ERROR; +} + +IA_ERRORCODE impd_drc_init_all_filter_banks( + const ia_drc_coefficients_uni_drc_struct *pstr_drc_coefficients_uni_drc, + const ia_drc_instructions_uni_drc *pstr_drc_instructions_uni_drc, + ia_drc_filter_banks_struct *pstr_filter_banks, VOID *ptr_scratch) { + IA_ERRORCODE err_code = IA_NO_ERROR; + LOOPIDX band_idx, group_idx, i, j, k; + WORD32 crossover_freq_index, num_ch_in_groups, num_phase_alignment_ch_groups; + WORD32 index_found = FALSE; + WORD32 group_count[MAX_CHANNEL_GROUP_COUNT + 1] = {0}; + WORD32 *ptr_cascade_crossover_indices[MAX_CHANNEL_GROUP_COUNT + 1]; + + for (i = 0; i < MAX_CHANNEL_GROUP_COUNT + 1; i++) { + ptr_cascade_crossover_indices[i] = (WORD32 *)(ptr_scratch); + ptr_scratch = (UWORD8 *)ptr_scratch + + (MAX_CHANNEL_GROUP_COUNT * 3) * sizeof(ptr_cascade_crossover_indices[i][0]); + } + + num_ch_in_groups = 0; + for (group_idx = 0; group_idx < pstr_drc_instructions_uni_drc->num_drc_channel_groups; + group_idx++) { + num_ch_in_groups += pstr_drc_instructions_uni_drc->num_channels_per_channel_group[group_idx]; + } + num_phase_alignment_ch_groups = pstr_drc_instructions_uni_drc->num_drc_channel_groups; + if (num_ch_in_groups < pstr_drc_instructions_uni_drc->drc_channel_count) { + num_phase_alignment_ch_groups++; + } + if (num_phase_alignment_ch_groups > IMPD_DRCMAX_PHASE_ALIGN_CH_GROUP) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_PARAM_OUT_OF_RANGE; + } + + memset(pstr_filter_banks->str_drc_filter_bank, 0, + sizeof(pstr_filter_banks->str_drc_filter_bank)); + pstr_filter_banks->num_phase_alignment_ch_groups = num_phase_alignment_ch_groups; + pstr_filter_banks->num_filter_banks = pstr_drc_instructions_uni_drc->num_drc_channel_groups; + if (pstr_drc_coefficients_uni_drc != NULL) { + for (group_idx = 0; group_idx < pstr_drc_instructions_uni_drc->num_drc_channel_groups; + group_idx++) { + err_code = impd_drc_filter_bank_complexity( + pstr_drc_coefficients_uni_drc + ->str_gain_set_params[pstr_drc_instructions_uni_drc + ->gain_set_index_for_channel_group[group_idx]] + .band_count, + &(pstr_filter_banks->str_drc_filter_bank[group_idx])); + if (err_code) { + return err_code; + } + } + } else { + pstr_filter_banks->str_drc_filter_bank->num_bands = 1; + } + + if (pstr_drc_coefficients_uni_drc != NULL) { + for (group_idx = 0; group_idx < pstr_drc_instructions_uni_drc->num_drc_channel_groups; + group_idx++) { + for (band_idx = 1; + band_idx < pstr_drc_coefficients_uni_drc + ->str_gain_set_params[pstr_drc_instructions_uni_drc + ->gain_set_index_for_channel_group[group_idx]] + .band_count; + band_idx++) { + crossover_freq_index = + pstr_drc_coefficients_uni_drc + ->str_gain_set_params[pstr_drc_instructions_uni_drc + ->gain_set_index_for_channel_group[group_idx]] + .gain_params[band_idx] + .crossover_freq_index; + + for (j = 0; j < num_phase_alignment_ch_groups; j++) { + if (j != group_idx) { + ptr_cascade_crossover_indices[j][group_count[j]] = crossover_freq_index; + group_count[j]++; + if (group_count[j] > MAX_CHANNEL_GROUP_COUNT * 3) { + return IA_EXHEAACE_CONFIG_FATAL_DRC_PARAM_OUT_OF_RANGE; + } + } + } + } + } + } + + i = 0; + while (i < group_count[0]) { + crossover_freq_index = ptr_cascade_crossover_indices[0][i]; + index_found = FALSE; + for (group_idx = 1; group_idx < num_phase_alignment_ch_groups; group_idx++) { + index_found = FALSE; + for (j = 0; j < group_count[group_idx]; j++) { + if (ptr_cascade_crossover_indices[group_idx][j] == crossover_freq_index) { + index_found = TRUE; + break; + } + } + if (index_found == FALSE) { + break; + } + } + if (index_found == FALSE) { + i++; + } else { + for (group_idx = 0; group_idx < num_phase_alignment_ch_groups; group_idx++) { + for (j = 0; j < group_count[group_idx]; j++) { + if (ptr_cascade_crossover_indices[group_idx][j] == crossover_freq_index) { + for (k = j + 1; k < group_count[group_idx]; k++) { + ptr_cascade_crossover_indices[group_idx][k - 1] = + ptr_cascade_crossover_indices[group_idx][k]; + } + group_count[group_idx]--; + break; + } + } + } + i = 0; + } + } + for (group_idx = 0; group_idx < num_phase_alignment_ch_groups; group_idx++) { + if (group_count[group_idx] > 0) { + pstr_filter_banks->str_drc_filter_bank[group_idx].complexity += + (group_count[group_idx] << 1); + } + } + pstr_filter_banks->complexity = 0; + for (group_idx = 0; group_idx < pstr_drc_instructions_uni_drc->num_drc_channel_groups; + group_idx++) { + pstr_filter_banks->complexity += + pstr_drc_instructions_uni_drc->num_channels_per_channel_group[group_idx] * + pstr_filter_banks->str_drc_filter_bank[group_idx].complexity; + } + + return err_code; +} diff --git a/encoder/drc_src/impd_drc_uni_drc_filter_bank.h b/encoder/drc_src/impd_drc_uni_drc_filter_bank.h new file mode 100644 index 0000000..3fe2c48 --- /dev/null +++ b/encoder/drc_src/impd_drc_uni_drc_filter_bank.h @@ -0,0 +1,39 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +#define IMPD_DRCMAX_PHASE_ALIGN_CH_GROUP (32) + +typedef struct { + WORD32 num_bands; + WORD32 complexity; +} ia_drc_filter_bank_struct; + +typedef struct { + WORD32 num_filter_banks; + WORD32 num_phase_alignment_ch_groups; + WORD32 complexity; + ia_drc_filter_bank_struct str_drc_filter_bank[IMPD_DRCMAX_PHASE_ALIGN_CH_GROUP]; +} ia_drc_filter_banks_struct; + +IA_ERRORCODE impd_drc_init_all_filter_banks( + const ia_drc_coefficients_uni_drc_struct *pstr_drc_coefficients_uni_drc, + const ia_drc_instructions_uni_drc *pstr_drc_instructions_uni_drc, + ia_drc_filter_banks_struct *pstr_filter_banks, VOID *ptr_scratch); diff --git a/encoder/drc_src/libxaacenc_drc.cmake b/encoder/drc_src/libxaacenc_drc.cmake new file mode 100644 index 0000000..4aa108b --- /dev/null +++ b/encoder/drc_src/libxaacenc_drc.cmake @@ -0,0 +1,12 @@ +# src files +list( + APPEND + LIBXAACENC_SRCS + "${XAAC_ROOT}/encoder/drc_src/impd_drc_api.c" + "${XAAC_ROOT}/encoder/drc_src/impd_drc_enc.c" + "${XAAC_ROOT}/encoder/drc_src/impd_drc_gain_calculator.c" + "${XAAC_ROOT}/encoder/drc_src/impd_drc_gain_enc.c" + "${XAAC_ROOT}/encoder/drc_src/impd_drc_mux.c" + "${XAAC_ROOT}/encoder/drc_src/impd_drc_tables.c" + "${XAAC_ROOT}/encoder/drc_src/impd_drc_uni_drc_eq.c" + "${XAAC_ROOT}/encoder/drc_src/impd_drc_uni_drc_filter_bank.c") diff --git a/encoder/iusace_acelp_enc.c b/encoder/iusace_acelp_enc.c new file mode 100644 index 0000000..5def828 --- /dev/null +++ b/encoder/iusace_acelp_enc.c @@ -0,0 +1,439 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include +#include "ixheaac_type_def.h" +#include "iusace_bitbuffer.h" + +/* DRC */ +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" +#include "impd_drc_uni_drc_eq.h" +#include "impd_drc_uni_drc_filter_bank.h" +#include "impd_drc_gain_enc.h" +#include "impd_drc_struct_def.h" + +#include "iusace_cnst.h" +#include "iusace_tns_usac.h" +#include "iusace_psy_mod.h" +#include "ixheaace_adjust_threshold_data.h" +#include "iusace_fd_qc_util.h" +#include "iusace_config.h" +#include "iusace_arith_enc.h" +#include "iusace_block_switch_const.h" +#include "iusace_block_switch_struct_def.h" +#include "iusace_lpd_rom.h" +#include "iusace_lpd.h" + +VOID iusace_acelp_encode(FLOAT32 *lp_filt_coeff, FLOAT32 *quant_lp_filt_coeff, FLOAT32 *speech_in, + FLOAT32 *wsig_in, FLOAT32 *synth_out, FLOAT32 *wsynth_out, + WORD16 acelp_core_mode, ia_usac_lpd_state_struct *lpd_state, + WORD32 len_subfrm, FLOAT32 norm_corr, FLOAT32 norm_corr2, + WORD32 ol_pitch_lag1, WORD32 ol_pitch_lag2, WORD32 pit_adj, + WORD32 *acelp_params, iusace_scratch_mem *pstr_scratch) { + WORD32 i, i_subfr, num_bits, t; + WORD32 t0, t0_min, t0_max, index, subfrm_flag; + WORD32 t0_frac; + FLOAT32 temp, energy, max_ener, mean_ener_code; + FLOAT32 pitch_gain, code_gain, gain1, gain2; + FLOAT32 tgt_cb_corr[5], tgt_cb_corr2[2]; + FLOAT32 *p_lp_filt_coeff, *p_quant_lp_filt_coeff, weighted_lpc[ORDER + 1]; + FLOAT32 imp_res[LEN_SUBFR]; + FLOAT32 code[LEN_SUBFR]; + WORD16 cb_exc[LEN_SUBFR]; + FLOAT32 error[ORDER + LEN_SUBFR + 8]; + FLOAT32 cn[LEN_SUBFR]; + FLOAT32 xn[LEN_SUBFR]; + FLOAT32 xn2[LEN_SUBFR]; + FLOAT32 dn[LEN_SUBFR]; + FLOAT32 y0[LEN_SUBFR]; + FLOAT32 y1[LEN_SUBFR]; + FLOAT32 y2[LEN_SUBFR]; + WORD32 min_pitch_lag_res1_4; + WORD32 min_pitch_lag_res1_2; + WORD32 min_pitch_lag_res1; + WORD32 max_pitch_lag; + FLOAT32 *exc_buf = pstr_scratch->p_acelp_exc_buf; + FLOAT32 *exc; + FLOAT32 mem_txn, mem_txnq; + WORD32 fac_length = len_subfrm / 2; + if (lpd_state->mode > 0) { + for (i = 0; i < fac_length; i++) { + acelp_params[i] = lpd_state->avq_params[i]; + } + acelp_params += fac_length; + } + + if (pit_adj == SR_MAX) + exc = exc_buf + (2 * len_subfrm) + 41; + else + exc = exc_buf + (2 * len_subfrm); + + memset(exc_buf, 0, (2 * len_subfrm) * sizeof(exc_buf[0])); + memcpy(exc_buf, lpd_state->acelp_exc, 2 * len_subfrm * sizeof(FLOAT32)); + memcpy(synth_out - 128, &(lpd_state->synth[ORDER]), 128 * sizeof(FLOAT32)); + memcpy(wsynth_out - 128, &(lpd_state->wsynth[1]), 128 * sizeof(FLOAT32)); + + num_bits = ((iusace_acelp_core_numbits_1024[acelp_core_mode] - NBITS_MODE) / 4) - NBITS_LPC; + + if (pit_adj == 0) { + min_pitch_lag_res1_4 = TMIN; + min_pitch_lag_res1_2 = TFR2; + min_pitch_lag_res1 = TFR1; + max_pitch_lag = TMAX; + } else { + i = (((pit_adj * TMIN) + (FSCALE_DENOM / 2)) / FSCALE_DENOM) - TMIN; + min_pitch_lag_res1_4 = TMIN + i; + min_pitch_lag_res1_2 = TFR2 - i; + min_pitch_lag_res1 = TFR1; + max_pitch_lag = TMAX + (6 * i); + } + + ol_pitch_lag1 *= OPL_DECIM; + ol_pitch_lag2 *= OPL_DECIM; + + t0_min = ol_pitch_lag1 - 8; + + t = MIN(ol_pitch_lag1, ol_pitch_lag2) - 4; + if (t0_min < t) t0_min = t; + + if (t0_min < min_pitch_lag_res1_4) { + t0_min = min_pitch_lag_res1_4; + } + t0_max = t0_min + 15; + t = MAX(ol_pitch_lag1, ol_pitch_lag2) + 4; + if (t0_max > t) t0_max = t; + + if (t0_max > max_pitch_lag) { + t0_max = max_pitch_lag; + t0_min = t0_max - 15; + } + + max_ener = 0.0; + mean_ener_code = 0.0; + p_quant_lp_filt_coeff = quant_lp_filt_coeff; + for (i_subfr = 0; i_subfr < len_subfrm; i_subfr += LEN_SUBFR) { + iusace_compute_lp_residual(p_quant_lp_filt_coeff, &speech_in[i_subfr], &exc[i_subfr], + LEN_SUBFR); + energy = 0.01f; + for (i = 0; i < LEN_SUBFR; i++) { + energy += exc[i + i_subfr] * exc[i + i_subfr]; + } + energy = 10.0f * (FLOAT32)log10(energy / ((FLOAT32)LEN_SUBFR)); + if (energy < 0.0) { + energy = 0.0; + } + if (energy > max_ener) { + max_ener = energy; + } + mean_ener_code += 0.25f * energy; + p_quant_lp_filt_coeff += (ORDER + 1); + } + + mean_ener_code -= 5.0f * norm_corr; + mean_ener_code -= 5.0f * norm_corr2; + + temp = (mean_ener_code - 18.0f) / 12.0f; + index = (WORD32)floor(temp + 0.5); + if (index < 0) { + index = 0; + } + if (index > 3) { + index = 3; + } + mean_ener_code = (((FLOAT32)index) * 12.0f) + 18.0f; + + while ((mean_ener_code < (max_ener - 27.0)) && (index < 3)) { + index++; + mean_ener_code += 12.0; + } + *acelp_params = index; + acelp_params++; + + p_lp_filt_coeff = lp_filt_coeff; + p_quant_lp_filt_coeff = quant_lp_filt_coeff; + for (i_subfr = 0; i_subfr < len_subfrm; i_subfr += LEN_SUBFR) { + subfrm_flag = i_subfr; + if ((len_subfrm == 256) && (i_subfr == (2 * LEN_SUBFR))) { + subfrm_flag = 0; + + t0_min = ol_pitch_lag2 - 8; + + t = MIN(ol_pitch_lag1, ol_pitch_lag2) - 4; + if (t0_min < t) t0_min = t; + + if (t0_min < min_pitch_lag_res1_4) { + t0_min = min_pitch_lag_res1_4; + } + t0_max = t0_min + 15; + + t = MAX(ol_pitch_lag1, ol_pitch_lag2) + 4; + if (t0_max > t) t0_max = t; + + if (t0_max > max_pitch_lag) { + t0_max = max_pitch_lag; + t0_min = t0_max - 15; + } + } + + memcpy(xn, &wsig_in[i_subfr], LEN_SUBFR * sizeof(FLOAT32)); + + memcpy(error, &synth_out[i_subfr - ORDER], ORDER * sizeof(FLOAT32)); + memset(error + ORDER, 0, LEN_SUBFR * sizeof(FLOAT32)); + iusace_synthesis_tool_float(p_quant_lp_filt_coeff, error + ORDER, error + ORDER, LEN_SUBFR, + error, pstr_scratch->p_buf_synthesis_tool); + iusace_get_weighted_lpc(p_lp_filt_coeff, weighted_lpc); + iusace_compute_lp_residual(weighted_lpc, error + ORDER, xn2, LEN_SUBFR); + + temp = wsynth_out[i_subfr - 1]; + iusace_apply_deemph(xn2, TILT_FAC, LEN_SUBFR, &temp); + memcpy(y0, xn2, LEN_SUBFR * sizeof(FLOAT32)); + + for (i = 0; i < LEN_SUBFR; i++) { + xn[i] -= xn2[i]; + } + iusace_compute_lp_residual(p_quant_lp_filt_coeff, &speech_in[i_subfr], &exc[i_subfr], + LEN_SUBFR); + + memset(&code[0], 0, ORDER * sizeof(code[0])); + memcpy(code + ORDER, xn, (LEN_SUBFR / 2) * sizeof(FLOAT32)); + temp = 0.0; + iusace_apply_preemph(code + ORDER, TILT_FAC, LEN_SUBFR / 2, &temp); + iusace_get_weighted_lpc(p_lp_filt_coeff, weighted_lpc); + iusace_synthesis_tool_float(weighted_lpc, code + ORDER, code + ORDER, LEN_SUBFR / 2, code, + pstr_scratch->p_buf_synthesis_tool); + iusace_compute_lp_residual(p_quant_lp_filt_coeff, code + ORDER, cn, LEN_SUBFR / 2); + memcpy(cn + (LEN_SUBFR / 2), &exc[i_subfr + (LEN_SUBFR / 2)], + (LEN_SUBFR / 2) * sizeof(FLOAT32)); + + iusace_get_weighted_lpc(p_lp_filt_coeff, weighted_lpc); + memset(imp_res, 0, LEN_SUBFR * sizeof(FLOAT32)); + memcpy(imp_res, weighted_lpc, (ORDER + 1) * sizeof(FLOAT32)); + iusace_synthesis_tool_float(p_quant_lp_filt_coeff, imp_res, imp_res, LEN_SUBFR, + &imp_res[ORDER + 1], pstr_scratch->p_buf_synthesis_tool); + temp = 0.0; + iusace_apply_deemph(imp_res, TILT_FAC, LEN_SUBFR, &temp); + + iusace_closed_loop_search(&exc[i_subfr], xn, imp_res, t0_min, t0_max, &t0_frac, subfrm_flag, + min_pitch_lag_res1_2, min_pitch_lag_res1, &t0); + + if (subfrm_flag == 0) { + if (t0 < min_pitch_lag_res1_2) { + index = t0 * 4 + t0_frac - (min_pitch_lag_res1_4 * 4); + } else if (t0 < min_pitch_lag_res1) { + index = t0 * 2 + (t0_frac >> 1) - (min_pitch_lag_res1_2 * 2) + + ((min_pitch_lag_res1_2 - min_pitch_lag_res1_4) * 4); + } else { + index = t0 - min_pitch_lag_res1 + ((min_pitch_lag_res1_2 - min_pitch_lag_res1_4) * 4) + + ((min_pitch_lag_res1 - min_pitch_lag_res1_2) * 2); + } + + t0_min = t0 - 8; + if (t0_min < min_pitch_lag_res1_4) { + t0_min = min_pitch_lag_res1_4; + } + t0_max = t0_min + 15; + if (t0_max > max_pitch_lag) { + t0_max = max_pitch_lag; + t0_min = t0_max - 15; + } + } else { + i = t0 - t0_min; + index = i * 4 + t0_frac; + } + *acelp_params = index; + acelp_params++; + + iusace_acelp_ltpred_cb_exc(&exc[i_subfr], t0, t0_frac, LEN_SUBFR + 1); + iusace_convolve(&exc[i_subfr], imp_res, y1); + gain1 = iusace_acelp_tgt_cb_corr2(xn, y1, tgt_cb_corr); + iusace_acelp_cb_target_update(xn, xn2, y1, gain1); + energy = 0.0; + for (i = 0; i < LEN_SUBFR; i++) { + energy += xn2[i] * xn2[i]; + } + + for (i = 0; i < LEN_SUBFR; i++) { + code[i] = (FLOAT32)(0.18 * exc[i - 1 + i_subfr] + 0.64 * exc[i + i_subfr] + + 0.18 * exc[i + 1 + i_subfr]); + } + iusace_convolve(code, imp_res, y2); + gain2 = iusace_acelp_tgt_cb_corr2(xn, y2, tgt_cb_corr2); + + iusace_acelp_cb_target_update(xn, xn2, y2, gain2); + temp = 0.0; + for (i = 0; i < LEN_SUBFR; i++) { + temp += xn2[i] * xn2[i]; + } + + if (temp < energy) { + *acelp_params = 0; + memcpy(&exc[i_subfr], code, LEN_SUBFR * sizeof(FLOAT32)); + memcpy(y1, y2, LEN_SUBFR * sizeof(FLOAT32)); + pitch_gain = gain2; + tgt_cb_corr[0] = tgt_cb_corr2[0]; + tgt_cb_corr[1] = tgt_cb_corr2[1]; + } else { + *acelp_params = 1; + pitch_gain = gain1; + } + acelp_params++; + + iusace_acelp_cb_target_update(xn, xn2, y1, pitch_gain); + iusace_acelp_cb_target_update(cn, cn, &exc[i_subfr], pitch_gain); + + temp = 0.0; + iusace_apply_preemph(imp_res, TILT_CODE, LEN_SUBFR, &temp); + if (t0_frac > 2) { + t0++; + } + + for (i = t0; i < LEN_SUBFR; i++) { + imp_res[i] += imp_res[i - t0] * PIT_SHARP; + } + + iusace_acelp_tgt_ir_corr(xn2, imp_res, dn); + + if (acelp_core_mode == ACELP_CORE_MODE_9k6) { + iusace_acelp_cb_exc(dn, cn, imp_res, cb_exc, y2, ACELP_NUM_BITS_20, acelp_params, + pstr_scratch->p_acelp_ir_buf); + acelp_params += 4; + } else if (acelp_core_mode == ACELP_CORE_MODE_11k2) { + iusace_acelp_cb_exc(dn, cn, imp_res, cb_exc, y2, ACELP_NUM_BITS_28, acelp_params, + pstr_scratch->p_acelp_ir_buf); + acelp_params += 4; + } else if (acelp_core_mode == ACELP_CORE_MODE_12k8) { + iusace_acelp_cb_exc(dn, cn, imp_res, cb_exc, y2, ACELP_NUM_BITS_36, acelp_params, + pstr_scratch->p_acelp_ir_buf); + acelp_params += 4; + } else if (acelp_core_mode == ACELP_CORE_MODE_14k4) { + iusace_acelp_cb_exc(dn, cn, imp_res, cb_exc, y2, ACELP_NUM_BITS_44, acelp_params, + pstr_scratch->p_acelp_ir_buf); + acelp_params += 4; + } else if (acelp_core_mode == ACELP_CORE_MODE_16k) { + iusace_acelp_cb_exc(dn, cn, imp_res, cb_exc, y2, ACELP_NUM_BITS_52, acelp_params, + pstr_scratch->p_acelp_ir_buf); + acelp_params += 4; + } else if (acelp_core_mode == ACELP_CORE_MODE_18k4) { + iusace_acelp_cb_exc(dn, cn, imp_res, cb_exc, y2, ACELP_NUM_BITS_64, acelp_params, + pstr_scratch->p_acelp_ir_buf); + acelp_params += 8; + } else { + iusace_acelp_cb_exc(dn, cn, imp_res, cb_exc, y2, ACELP_NUM_BITS_64, acelp_params, + pstr_scratch->p_acelp_ir_buf); + acelp_params += 8; + } + + for (i = 0; i < LEN_SUBFR; i++) { + code[i] = (FLOAT32)(cb_exc[i] / 512); + } + + temp = 0.0; + iusace_apply_preemph(code, TILT_CODE, LEN_SUBFR, &temp); + for (i = t0; i < LEN_SUBFR; i++) { + code[i] += code[i - t0] * PIT_SHARP; + } + + iusace_acelp_tgt_cb_corr1(xn, y1, y2, tgt_cb_corr); + iusace_acelp_quant_gain(code, &pitch_gain, &code_gain, tgt_cb_corr, mean_ener_code, + acelp_params); + acelp_params++; + + temp = 0.0; + for (i = 0; i < LEN_SUBFR; i++) { + temp += code[i] * code[i]; + } + temp *= code_gain * code_gain; + + for (i = 0; i < LEN_SUBFR; i++) { + wsynth_out[i + i_subfr] = y0[i] + (pitch_gain * y1[i]) + (code_gain * y2[i]); + } + + for (i = 0; i < LEN_SUBFR; i++) { + exc[i + i_subfr] = pitch_gain * exc[i + i_subfr] + code_gain * code[i]; + } + + iusace_synthesis_tool_float(p_quant_lp_filt_coeff, &exc[i_subfr], &synth_out[i_subfr], + LEN_SUBFR, &synth_out[i_subfr - ORDER], + pstr_scratch->p_buf_synthesis_tool); + p_lp_filt_coeff += (ORDER + 1); + p_quant_lp_filt_coeff += (ORDER + 1); + } + + memcpy(lpd_state->acelp_exc, exc - len_subfrm, 2 * len_subfrm * sizeof(FLOAT32)); + memcpy(lpd_state->synth, synth_out + len_subfrm - (ORDER + 128), + (ORDER + 128) * sizeof(FLOAT32)); + memcpy(lpd_state->wsynth, wsynth_out + len_subfrm - (1 + 128), (1 + 128) * sizeof(FLOAT32)); + memcpy(lpd_state->lpc_coeffs_quant, p_quant_lp_filt_coeff - (2 * (ORDER + 1)), + (2 * (ORDER + 1)) * sizeof(FLOAT32)); + memcpy(lpd_state->lpc_coeffs, p_lp_filt_coeff - (2 * (ORDER + 1)), + (2 * (ORDER + 1)) * sizeof(FLOAT32)); + + mem_txn = lpd_state->tcx_mem[128 - 1]; + mem_txnq = lpd_state->tcx_fac; + + p_quant_lp_filt_coeff = quant_lp_filt_coeff; + for (i_subfr = 0; i_subfr < (len_subfrm - 2 * LEN_SUBFR); i_subfr += LEN_SUBFR) { + iusace_get_weighted_lpc(p_quant_lp_filt_coeff, weighted_lpc); + + memcpy(error, &speech_in[i_subfr], LEN_SUBFR * sizeof(FLOAT32)); + iusace_apply_deemph(error, TILT_FAC, LEN_SUBFR, &mem_txn); + + memcpy(error, &synth_out[i_subfr], LEN_SUBFR * sizeof(FLOAT32)); + iusace_apply_deemph(error, TILT_FAC, LEN_SUBFR, &mem_txnq); + + p_quant_lp_filt_coeff += (ORDER + 1); + } + + lpd_state->tcx_quant[0] = mem_txnq; + for (i_subfr = 0; i_subfr < (2 * LEN_SUBFR); i_subfr += LEN_SUBFR) { + iusace_get_weighted_lpc(p_quant_lp_filt_coeff, weighted_lpc); + + memcpy(&(lpd_state->tcx_mem[i_subfr]), &speech_in[i_subfr + (len_subfrm - 2 * LEN_SUBFR)], + LEN_SUBFR * sizeof(FLOAT32)); + iusace_apply_deemph(&(lpd_state->tcx_mem[i_subfr]), TILT_FAC, LEN_SUBFR, &mem_txn); + + memcpy(&(lpd_state->tcx_quant[1 + i_subfr]), + &synth_out[i_subfr + (len_subfrm - 2 * LEN_SUBFR)], LEN_SUBFR * sizeof(FLOAT32)); + iusace_apply_deemph(&(lpd_state->tcx_quant[1 + i_subfr]), TILT_FAC, LEN_SUBFR, &mem_txnq); + p_quant_lp_filt_coeff += (ORDER + 1); + } + lpd_state->tcx_fac = mem_txnq; + + iusace_get_weighted_lpc(p_quant_lp_filt_coeff, weighted_lpc); + + memcpy(error, &synth_out[len_subfrm - ORDER], ORDER * sizeof(FLOAT32)); + for (i_subfr = (2 * LEN_SUBFR); i_subfr < (4 * LEN_SUBFR); i_subfr += LEN_SUBFR) { + memset(error + ORDER, 0, LEN_SUBFR * sizeof(FLOAT32)); + + iusace_synthesis_tool_float(p_quant_lp_filt_coeff, error + ORDER, error + ORDER, LEN_SUBFR, + error, pstr_scratch->p_buf_synthesis_tool); + memcpy(&(lpd_state->tcx_quant[1 + i_subfr]), error + ORDER, LEN_SUBFR * sizeof(FLOAT32)); + iusace_apply_deemph(&(lpd_state->tcx_quant[1 + i_subfr]), TILT_FAC, LEN_SUBFR, &mem_txnq); + memcpy(error, error + LEN_SUBFR, ORDER * sizeof(FLOAT32)); + } + + lpd_state->mode = 0; + + lpd_state->num_bits = num_bits; +} diff --git a/encoder/iusace_acelp_rom.c b/encoder/iusace_acelp_rom.c new file mode 100644 index 0000000..c3749f9 --- /dev/null +++ b/encoder/iusace_acelp_rom.c @@ -0,0 +1,213 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include "ixheaac_type_def.h" +#include "iusace_cnst.h" + +const UWORD8 iusace_acelp_ipos[36] = {0, 1, 2, 3, 1, 2, 3, 0, 2, 3, 0, 1, 3, 0, 1, 2, 0, 1, + 2, 3, 1, 2, 3, 0, 2, 3, 0, 1, 3, 0, 1, 2, 0, 1, 2, 3}; + +const FLOAT32 iusace_chebyshev_polyn_grid[101] = { + 1.00000F, 0.999507F, 0.998027F, 0.995562F, 0.992115F, 0.987688F, 0.982287F, + 0.975917F, 0.968583F, 0.960294F, 0.951057F, 0.940881F, 0.929776F, 0.917755F, + 0.904827F, 0.891007F, 0.876307F, 0.860742F, 0.844328F, 0.827081F, 0.809017F, + 0.790155F, 0.770513F, 0.750111F, 0.728969F, 0.707107F, 0.684547F, 0.661312F, + 0.637424F, 0.612907F, 0.587785F, 0.562083F, 0.535827F, 0.509041F, 0.481754F, + 0.453990F, 0.425779F, 0.397148F, 0.368124F, 0.338738F, 0.309017F, 0.278991F, + 0.248690F, 0.218143F, 0.187381F, 0.156434F, 0.125333F, 0.0941082F, 0.0627904F, + 0.0314107F, -8.09643e-008F, -0.0314108F, -0.0627906F, -0.0941084F, -0.125333F, -0.156435F, + -0.187381F, -0.218143F, -0.248690F, -0.278991F, -0.309017F, -0.338738F, -0.368125F, + -0.397148F, -0.425779F, -0.453991F, -0.481754F, -0.509041F, -0.535827F, -0.562083F, + -0.587785F, -0.612907F, -0.637424F, -0.661312F, -0.684547F, -0.707107F, -0.728969F, + -0.750111F, -0.770513F, -0.790155F, -0.809017F, -0.827081F, -0.844328F, -0.860742F, + -0.876307F, -0.891007F, -0.904827F, -0.917755F, -0.929777F, -0.940881F, -0.951057F, + -0.960294F, -0.968583F, -0.975917F, -0.982287F, -0.987688F, -0.992115F, -0.995562F, + -0.998027F, -0.999507F, -1.00000F}; + +const FLOAT32 iusace_ol_corr_weight[518] = { + 0.221587981217023f, 0.222261823815225f, 0.222935666413414f, 0.223609509011589f, + 0.224283351609750f, 0.224957194207899f, 0.225631036806034f, 0.226304879404157f, + 0.226978722002268f, 0.227652564600366f, 0.228326407198452f, 0.229000249796527f, + 0.229674092394590f, 0.230347934992642f, 0.231021777590682f, 0.231695620188712f, + 0.232369462786731f, 0.233043305384739f, 0.233717147982738f, 0.234390990580726f, + 0.235064833178704f, 0.235738675776673f, 0.236412518374633f, 0.237086360972583f, + 0.237760203570524f, 0.238434046168457f, 0.239107888766381f, 0.239781731364297f, + 0.240455573962205f, 0.241129416560105f, 0.241803259157998f, 0.242477101755883f, + 0.243150944353761f, 0.243824786951632f, 0.244498629549496f, 0.245172472147353f, + 0.245846314745205f, 0.246520157343050f, 0.247193999940890f, 0.247867842538723f, + 0.248541685136552f, 0.249215527734375f, 0.249889370332193f, 0.250563212930007f, + 0.251237055527815f, 0.251910898125620f, 0.252584740723420f, 0.253258583321217f, + 0.253932425919010f, 0.254606268516799f, 0.255280111114586f, 0.255953953712369f, + 0.256627796310149f, 0.257301638907927f, 0.257975481505702f, 0.258649324103476f, + 0.259323166701247f, 0.259997009299017f, 0.260670851896785f, 0.261344694494552f, + 0.262018537092318f, 0.262692379690083f, 0.263366222287848f, 0.263366222287847f, + 0.264040064885612f, 0.264713907483376f, 0.265387750081140f, 0.266061592678904f, + 0.266735435276667f, 0.267409277874430f, 0.268083120472194f, 0.268756963069956f, + 0.269430805667719f, 0.270104648265482f, 0.270778490863244f, 0.271452333461006f, + 0.272126176058768f, 0.272800018656529f, 0.273473861254291f, 0.274147703852052f, + 0.274821546449814f, 0.275495389047575f, 0.276169231645336f, 0.276843074243096f, + 0.277516916840857f, 0.278190759438618f, 0.278864602036378f, 0.279538444634139f, + 0.280212287231899f, 0.280886129829659f, 0.281559972427420f, 0.282233815025180f, + 0.282907657622940f, 0.283581500220700f, 0.284255342818460f, 0.284929185416220f, + 0.285603028013980f, 0.286276870611740f, 0.286950713209500f, 0.287624555807260f, + 0.288298398405020f, 0.288972241002780f, 0.289646083600540f, 0.290319926198300f, + 0.290993768796060f, 0.291667611393820f, 0.292341453991580f, 0.293015296589340f, + 0.293689139187100f, 0.294362981784860f, 0.295036824382620f, 0.295710666980380f, + 0.296384509578140f, 0.297058352175900f, 0.297732194773660f, 0.298406037371420f, + 0.299079879969180f, 0.299753722566940f, 0.300427565164700f, 0.301101407762460f, + 0.301775250360220f, 0.302449092957980f, 0.303122935555740f, 0.303796778153500f, + 0.304470620751260f, 0.305144463349020f, 0.305818305946780f, 0.306492148544540f, + 0.307165991142300f, 0.307839833740060f, 0.308513676337820f, 0.309187518935580f, + 0.309861361533340f, 0.310535204131100f, 0.311209046728860f, 0.311882889326620f, + 0.312556731924380f, 0.313230574522140f, 0.313904417119900f, 0.314578259717660f, + 0.315252102315420f, 0.315925944913180f, 0.316599787510940f, 0.317273630108700f, + 0.317947472706460f, 0.318621315304220f, 0.319295157901980f, 0.319969000499740f, + 0.320642843097500f, 0.321316685695260f, 0.321990528293020f, 0.322664370890780f, + 0.323338213488540f, 0.324012056086300f, 0.324685898684060f, 0.325359741281820f, + 0.326033583879580f, 0.326707426477340f, 0.327381269075100f, 0.328055111672860f, + 0.328728954270620f, 0.329402796868380f, 0.330083976070000f, 0.330772637748820f, + 0.331468932014340f, 0.332173013374690f, 0.332885040906940f, 0.333605178435610f, + 0.334333594719850f, 0.335070463649910f, 0.335815964453310f, 0.336570281911320f, + 0.337333606586500f, 0.338106135061810f, 0.338888070192030f, 0.339679621368370f, + 0.340481004796980f, 0.341292443792250f, 0.342114169085970f, 0.342946419153120f, + 0.343789440555740f, 0.344643488305690f, 0.345508826247860f, 0.346385727465050f, + 0.347274474706060f, 0.348175360838540f, 0.349088689328410f, 0.350014774747620f, + 0.350953943312400f, 0.351906533454040f, 0.352872896424760f, 0.353853396941050f, + 0.354848413867530f, 0.355858340944150f, 0.356883587560250f, 0.357924579578940f, + 0.358981760215980f, 0.360055590977160f, 0.361146552659300f, 0.362255146419720f, + 0.363381894919980f, 0.364527343550210f, 0.365692061740660f, 0.366876644368180f, + 0.368081713265840f, 0.369307918844770f, 0.370555941838460f, 0.371826495180490f, + 0.373120326028240f, 0.374438217946110f, 0.375780993263580f, 0.377149515625000f, + 0.378544692749950f, 0.379967479425290f, 0.381418880752330f, 0.382899955675540f, + 0.384411820822400f, 0.385955654687440f, 0.387532702198100f, 0.389144279704500f, + 0.390791780440810f, 0.392476680512480f, 0.394200545470490f, 0.395965037542720f, + 0.397771923602130f, 0.399623083962790f, 0.401520522108530f, 0.403466375474260f, + 0.405462927418450f, 0.407512620547120f, 0.409618071574760f, 0.411782087938380f, + 0.414007686416520f, 0.416298114048290f, 0.418656871699000f, 0.421087740681110f, + 0.423594812914300f, 0.426182525199670f, 0.428855698294360f, 0.431619581609630f, + 0.434479904523260f, 0.437442935506450f, 0.440515550524830f, 0.443705312500000f, + 0.447020564029760f, 0.450470536088870f, 0.454065476102870f, 0.457816799652350f, + 0.461737271191160f, 0.465841220638500f, 0.470144804662100f, 0.474666324087360f, + 0.479426612408380f, 0.484449515221620f, 0.490000000000000f, 0.500000000000000f, + 0.500000000000000f, 0.500000000000000f, 0.500000000000000f, 0.500000000000000f, + 0.500000000000000f, 0.500000000000000f, 0.490000000000000f, 0.484449515221620f, + 0.479426612408380f, 0.474666324087360f, 0.470144804662100f, 0.465841220638500f, + 0.461737271191160f, 0.457816799652350f, 0.454065476102870f, 0.450470536088870f, + 0.447020564029760f, 0.443705312500000f, 0.440515550524830f, 0.437442935506450f, + 0.434479904523260f, 0.431619581609630f, 0.428855698294360f, 0.426182525199670f, + 0.423594812914300f, 0.421087740681110f, 0.418656871699000f, 0.416298114048290f, + 0.414007686416520f, 0.411782087938380f, 0.409618071574760f, 0.407512620547120f, + 0.405462927418450f, 0.403466375474260f, 0.401520522108530f, 0.399623083962790f, + 0.397771923602130f, 0.395965037542720f, 0.394200545470490f, 0.392476680512480f, + 0.390791780440810f, 0.389144279704500f, 0.387532702198100f, 0.385955654687440f, + 0.384411820822400f, 0.382899955675540f, 0.381418880752330f, 0.379967479425290f, + 0.378544692749950f, 0.377149515625000f, 0.375780993263580f, 0.374438217946110f, + 0.373120326028240f, 0.371826495180490f, 0.370555941838460f, 0.369307918844770f, + 0.368081713265840f, 0.366876644368180f, 0.365692061740660f, 0.364527343550210f, + 0.363381894919980f, 0.362255146419720f, 0.361146552659300f, 0.360055590977160f, + 0.358981760215980f, 0.357924579578940f, 0.356883587560250f, 0.355858340944150f, + 0.354848413867530f, 0.353853396941050f, 0.352872896424760f, 0.351906533454040f, + 0.350953943312400f, 0.350014774747620f, 0.349088689328410f, 0.348175360838540f, + 0.347274474706060f, 0.346385727465050f, 0.345508826247860f, 0.344643488305690f, + 0.343789440555740f, 0.342946419153120f, 0.342114169085970f, 0.341292443792250f, + 0.340481004796980f, 0.339679621368370f, 0.338888070192030f, 0.338106135061810f, + 0.337333606586500f, 0.336570281911320f, 0.335815964453310f, 0.335070463649910f, + 0.334333594719850f, 0.333605178435610f, 0.332885040906940f, 0.332173013374690f, + 0.331468932014340f, 0.330772637748820f, 0.330083976070000f, 0.329402796868380f, + 0.328728954270620f, 0.328062306484320f, 0.327402715649920f, 0.328055111672860f, + 0.327381269075100f, 0.326707426477340f, 0.326033583879580f, 0.325359741281820f, + 0.324685898684060f, 0.324012056086300f, 0.323338213488540f, 0.322664370890780f, + 0.321990528293020f, 0.321316685695260f, 0.320642843097500f, 0.319969000499740f, + 0.319295157901980f, 0.318621315304220f, 0.317947472706460f, 0.317273630108700f, + 0.316599787510940f, 0.315925944913180f, 0.315252102315420f, 0.314578259717660f, + 0.313904417119900f, 0.313230574522140f, 0.312556731924380f, 0.311882889326620f, + 0.311209046728860f, 0.310535204131100f, 0.309861361533340f, 0.309187518935580f, + 0.308513676337820f, 0.307839833740060f, 0.307165991142300f, 0.306492148544540f, + 0.305818305946780f, 0.305144463349020f, 0.304470620751260f, 0.303796778153500f, + 0.303122935555740f, 0.302449092957980f, 0.301775250360220f, 0.301101407762460f, + 0.300427565164700f, 0.299753722566940f, 0.299079879969180f, 0.298406037371420f, + 0.297732194773660f, 0.297058352175900f, 0.296384509578140f, 0.295710666980380f, + 0.295036824382620f, 0.294362981784860f, 0.293689139187100f, 0.293015296589340f, + 0.292341453991580f, 0.291667611393820f, 0.290993768796060f, 0.290319926198300f, + 0.289646083600540f, 0.288972241002780f, 0.288298398405020f, 0.287624555807260f, + 0.286950713209500f, 0.286276870611740f, 0.285603028013980f, 0.284929185416220f, + 0.284255342818460f, 0.283581500220700f, 0.282907657622940f, 0.282233815025180f, + 0.281559972427420f, 0.280886129829659f, 0.280212287231899f, 0.279538444634139f, + 0.278864602036378f, 0.278190759438618f, 0.277516916840857f, 0.276843074243096f, + 0.276169231645336f, 0.275495389047575f, 0.274821546449814f, 0.274147703852052f, + 0.273473861254291f, 0.272800018656529f, 0.272126176058768f, 0.271452333461006f, + 0.270778490863244f, 0.270104648265482f, 0.269430805667719f, 0.268756963069956f, + 0.268083120472194f, 0.267409277874430f, 0.266735435276667f, 0.266061592678904f, + 0.265387750081140f, 0.264713907483376f, 0.264040064885612f, 0.263366222287848f, + 0.262692379690083f, 0.262018537092318f, 0.261344694494552f, 0.260670851896785f, + 0.259997009299017f, 0.259323166701247f, 0.258649324103476f, 0.257975481505702f, + 0.257301638907927f, 0.256627796310149f, 0.255953953712369f, 0.255280111114586f, + 0.254606268516799f, 0.253932425919010f, 0.253258583321217f, 0.252584740723420f, + 0.251910898125620f, 0.251237055527815f, 0.250563212930007f, 0.249889370332193f, + 0.249215527734375f, 0.248541685136552f, 0.247867842538723f, 0.247193999940890f, + 0.246520157343050f, 0.245846314745205f, 0.245172472147353f, 0.244498629549496f, + 0.243824786951632f, 0.243150944353761f, 0.242477101755883f, 0.241803259157998f, + 0.241129416560105f, 0.240455573962205f, 0.239781731364297f, 0.239107888766381f, + 0.238434046168457f, 0.237760203570524f, 0.237086360972583f, 0.236412518374633f, + 0.235738675776673f, 0.235064833178704f, 0.234390990580726f, 0.233717147982738f, + 0.233043305384739f, 0.232369462786731f, 0.231695620188712f, 0.231021777590682f, + 0.230347934992642f, 0.229674092394590f, 0.229000249796527f, 0.228326407198452f, + 0.227652564600366f, 0.226978722002268f, 0.226304879404157f, 0.225631036806034f, + 0.224957194207899f, 0.224283351609750f, 0.223609509011589f, 0.222935666413414f, + 0.222261823815225f, 0.221587981217023f}; + +const FLOAT32 iusace_acelp_quant_gain_table[NUM_QUANTIZATION_LEVEL * 2] = { + 0.012445F, 0.215546F, 0.028326F, 0.965442F, 0.053042F, 0.525819F, 0.065409F, 1.495322F, + 0.078212F, 2.323725F, 0.100504F, 0.751276F, 0.112617F, 3.427530F, 0.113124F, 0.309583F, + 0.121763F, 1.140685F, 0.143515F, 7.519609F, 0.162430F, 0.568752F, 0.164940F, 1.904113F, + 0.165429F, 4.947562F, 0.194985F, 0.855463F, 0.213527F, 1.281019F, 0.223544F, 0.414672F, + 0.243135F, 2.781766F, 0.257180F, 1.659565F, 0.269488F, 0.636749F, 0.286539F, 1.003938F, + 0.328124F, 2.225436F, 0.328761F, 0.330278F, 0.336807F, 11.500983F, 0.339794F, 3.805726F, + 0.344454F, 1.494626F, 0.346165F, 0.738748F, 0.363605F, 1.141454F, 0.398729F, 0.517614F, + 0.415276F, 2.928666F, 0.416282F, 0.862935F, 0.423421F, 1.873310F, 0.444151F, 0.202244F, + 0.445842F, 1.301113F, 0.455671F, 5.519512F, 0.484764F, 0.387607F, 0.488696F, 0.967884F, + 0.488730F, 0.666771F, 0.508189F, 1.516224F, 0.508792F, 2.348662F, 0.531504F, 3.883870F, + 0.548649F, 1.112861F, 0.551182F, 0.514986F, 0.564397F, 1.742030F, 0.566598F, 0.796454F, + 0.589255F, 3.081743F, 0.598816F, 1.271936F, 0.617654F, 0.333501F, 0.619073F, 2.040522F, + 0.625282F, 0.950244F, 0.630798F, 0.594883F, 0.638918F, 4.863197F, 0.650102F, 1.464846F, + 0.668412F, 0.747138F, 0.669490F, 2.583027F, 0.683757F, 1.125479F, 0.691216F, 1.739274F, + 0.718441F, 3.297789F, 0.722608F, 0.902743F, 0.728827F, 2.194941F, 0.729586F, 0.633849F, + 0.730907F, 7.432957F, 0.731017F, 0.431076F, 0.731543F, 1.387847F, 0.759183F, 1.045210F, + 0.768606F, 1.789648F, 0.771245F, 4.085637F, 0.772613F, 0.778145F, 0.786483F, 1.283204F, + 0.792467F, 2.412891F, 0.802393F, 0.544588F, 0.807156F, 0.255978F, 0.814280F, 1.544409F, + 0.817839F, 0.938798F, 0.826959F, 2.910633F, 0.830453F, 0.684066F, 0.833431F, 1.171532F, + 0.841208F, 1.908628F, 0.846440F, 5.333522F, 0.868280F, 0.841519F, 0.868662F, 1.435230F, + 0.871449F, 3.675784F, 0.881317F, 2.245058F, 0.882020F, 0.480249F, 0.882476F, 1.105804F, + 0.902856F, 0.684850F, 0.904419F, 1.682113F, 0.909384F, 2.787801F, 0.916558F, 7.500981F, + 0.918444F, 0.950341F, 0.919721F, 1.296319F, 0.940272F, 4.682978F, 0.940273F, 1.991736F, + 0.950291F, 3.507281F, 0.957455F, 1.116284F, 0.957723F, 0.793034F, 0.958217F, 1.497824F, + 0.962628F, 2.514156F, 0.968507F, 0.588605F, 0.974739F, 0.339933F, 0.991738F, 1.750201F, + 0.997210F, 0.936131F, 1.002422F, 1.250008F, 1.006040F, 2.167232F, 1.008848F, 3.129940F, + 1.014404F, 5.842819F, 1.027798F, 4.287319F, 1.039404F, 1.489295F, 1.039628F, 8.947958F, + 1.043214F, 0.765733F, 1.045089F, 2.537806F, 1.058994F, 1.031496F, 1.060415F, 0.478612F, + 1.072132F, 12.8F, 1.074778F, 1.910049F, 1.076570F, 15.9999F, 1.107853F, 3.843067F, + 1.110673F, 1.228576F, 1.110969F, 2.758471F, 1.140058F, 1.603077F, 1.155384F, 0.668935F, + 1.176229F, 6.717108F, 1.179008F, 2.011940F, 1.187735F, 0.963552F, 1.199569F, 4.891432F, + 1.206311F, 3.316329F, 1.215323F, 2.507536F, 1.223150F, 1.387102F, 1.296012F, 9.684225F}; + +const FLOAT32 iusace_interp4_1[17] = {0.900000F, 0.818959F, 0.604850F, 0.331379F, 0.083958F, + -0.075795F, -0.130717F, -0.105685F, -0.046774F, 0.004467F, + 0.027789F, 0.025642F, 0.012571F, 0.001927F, -0.001571F, + -0.000753F, 0.000000f}; diff --git a/encoder/iusace_acelp_tools.c b/encoder/iusace_acelp_tools.c new file mode 100644 index 0000000..952b0bd --- /dev/null +++ b/encoder/iusace_acelp_tools.c @@ -0,0 +1,1082 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include +#include "ixheaac_type_def.h" +#include "iusace_cnst.h" +#include "iusace_lpd_rom.h" + +static VOID iusace_acelp_ir_vec_corr1(FLOAT32 *ir, FLOAT32 *vec, UWORD8 track, FLOAT32 *sign, + FLOAT32 (*corr_ir)[16], FLOAT32 *corr_out, WORD32 *dn2_pos, + WORD32 num_pluse_pos) { + WORD16 i, j; + WORD32 dn; + WORD32 *dn2; + FLOAT32 *p0; + FLOAT32 s; + dn2 = &dn2_pos[track * 8]; + p0 = corr_ir[track]; + for (i = 0; i < num_pluse_pos; i++) { + dn = dn2[i]; + s = 0.0F; + for (j = 0; j < (LEN_SUBFR - dn); j++) { + s += ir[j] * vec[dn + j]; + } + corr_out[dn >> 2] = sign[dn] * s + p0[dn >> 2]; + } +} + +static VOID iusace_acelp_ir_vec_corr2(FLOAT32 *ir, FLOAT32 *vec, UWORD8 track, FLOAT32 *sign, + FLOAT32 (*corr_ir)[16], FLOAT32 *corr_out) { + WORD32 i, j; + FLOAT32 *p0; + FLOAT32 s; + p0 = corr_ir[track]; + for (i = 0; i < 16; i++) { + s = 0.0F; + for (j = 0; j < LEN_SUBFR - track; j++) { + s += ir[j] * vec[track + j]; + } + corr_out[i] = s * sign[track] + p0[i]; + track += 4; + } +} + +static VOID iusace_acelp_get_2p_pos(WORD32 nb_pos_ix, UWORD8 track_p1, UWORD8 track_p2, + FLOAT32 *corr_pulses, FLOAT32 *ener_pulses, WORD32 *pos_p1, + WORD32 *pos_p2, FLOAT32 *dn, WORD32 *dn2, FLOAT32 *corr_p1, + FLOAT32 *corr_p2, FLOAT32 (*corr_p1p2)[256]) { + WORD32 x, x2, y, x_save = 0, y_save = 0, i, *pos_x; + FLOAT32 ps0, alp0; + FLOAT32 ps1, ps2, sq, sqk; + FLOAT32 alp1, alp2, alpk; + FLOAT32 *p1, *p2; + FLOAT32 s; + pos_x = &dn2[track_p1 << 3]; + ps0 = *corr_pulses; + alp0 = *ener_pulses; + sqk = -1.0F; + alpk = 1.0F; + + for (i = 0; i < nb_pos_ix; i++) { + x = pos_x[i]; + x2 = x >> 2; + + ps1 = ps0 + dn[x]; + alp1 = alp0 + corr_p1[x2]; + p1 = corr_p2; + p2 = &corr_p1p2[track_p1][x2 << 4]; + for (y = track_p2; y < LEN_SUBFR; y += 4) { + ps2 = ps1 + dn[y]; + alp2 = alp1 + (*p1++) + (*p2++); + sq = ps2 * ps2; + s = (alpk * sq) - (sqk * alp2); + if (s > 0.0F) { + sqk = sq; + alpk = alp2; + y_save = y; + x_save = x; + } + } + } + *corr_pulses = ps0 + dn[x_save] + dn[y_save]; + *ener_pulses = alpk; + *pos_p1 = x_save; + *pos_p2 = y_save; +} + +static VOID iusace_acelp_get_1p_pos(UWORD8 track_p1, UWORD8 track_p2, FLOAT32 *corr_pulses, + FLOAT32 *alp, WORD32 *pos_p1, FLOAT32 *dn, FLOAT32 *corr_p1, + FLOAT32 *corr_p2) { + WORD32 x, x_save = 0; + FLOAT32 ps0, alp0; + FLOAT32 ps1, sq, sqk; + FLOAT32 alp1, alpk; + FLOAT32 s; + + ps0 = *corr_pulses; + alp0 = *alp; + sqk = -1.0F; + alpk = 1.0F; + + for (x = track_p1; x < LEN_SUBFR; x += 4) { + ps1 = ps0 + dn[x]; + alp1 = alp0 + corr_p1[x >> 2]; + sq = ps1 * ps1; + s = (alpk * sq) - (sqk * alp1); + if (s > 0.0F) { + sqk = sq; + alpk = alp1; + x_save = x; + } + } + + if (track_p2 != track_p1) { + for (x = track_p2; x < LEN_SUBFR; x += 4) { + ps1 = ps0 + dn[x]; + alp1 = alp0 + corr_p2[x >> 2]; + sq = ps1 * ps1; + s = (alpk * sq) - (sqk * alp1); + if (s > 0.0F) { + sqk = sq; + alpk = alp1; + x_save = x; + } + } + } + + *corr_pulses = ps0 + dn[x_save]; + *alp = alpk; + *pos_p1 = x_save; +} + +static WORD32 iusace_acelp_quant_1p_n1bits(WORD32 pos_pulse, WORD32 num_bits_pos) { + WORD32 mask; + WORD32 index; + mask = ((1 << num_bits_pos) - 1); + + index = (pos_pulse & mask); + if ((pos_pulse & 16) != 0) { + index += 1 << num_bits_pos; + } + return (index); +} + +static WORD32 iusace_acelp_quant_2p_2n1bits(WORD32 pos_p1, WORD32 pos_p2, WORD32 num_bits_pos) { + WORD32 mask; + WORD32 index; + mask = ((1 << num_bits_pos) - 1); + + if (((pos_p2 ^ pos_p1) & 16) == 0) { + if ((pos_p1 - pos_p2) <= 0) { + index = ((pos_p1 & mask) << num_bits_pos) + (pos_p2 & mask); + } else { + index = ((pos_p2 & mask) << num_bits_pos) + (pos_p1 & mask); + } + if ((pos_p1 & 16) != 0) { + index += 1 << (2 * num_bits_pos); + } + } else { + if (((pos_p1 & mask) - (pos_p2 & mask)) <= 0) { + index = ((pos_p2 & mask) << num_bits_pos) + (pos_p1 & mask); + if ((pos_p2 & 16) != 0) { + index += 1 << (2 * num_bits_pos); + } + } else { + index = ((pos_p1 & mask) << num_bits_pos) + (pos_p2 & mask); + if ((pos_p1 & 16) != 0) { + index += 1 << (2 * num_bits_pos); + } + } + } + return (index); +} + +static WORD32 iusace_acelp_quant_3p_3n1bits(WORD32 pos_p1, WORD32 pos_p2, WORD32 pos_p3, + WORD32 num_bits_pos) { + WORD32 nb_pos; + WORD32 index; + nb_pos = (1 << (num_bits_pos - 1)); + + if (((pos_p1 ^ pos_p2) & nb_pos) == 0) { + index = iusace_acelp_quant_2p_2n1bits(pos_p1, pos_p2, (num_bits_pos - 1)); + index += (pos_p1 & nb_pos) << num_bits_pos; + index += iusace_acelp_quant_1p_n1bits(pos_p3, num_bits_pos) << (2 * num_bits_pos); + } else if (((pos_p1 ^ pos_p3) & nb_pos) == 0) { + index = iusace_acelp_quant_2p_2n1bits(pos_p1, pos_p3, (num_bits_pos - 1)); + index += (pos_p1 & nb_pos) << num_bits_pos; + index += iusace_acelp_quant_1p_n1bits(pos_p2, num_bits_pos) << (2 * num_bits_pos); + } else { + index = iusace_acelp_quant_2p_2n1bits(pos_p2, pos_p3, (num_bits_pos - 1)); + index += (pos_p2 & nb_pos) << num_bits_pos; + index += iusace_acelp_quant_1p_n1bits(pos_p1, num_bits_pos) << (2 * num_bits_pos); + } + return (index); +} + +static WORD32 iusace_acelp_quant_4p_4n1bits(WORD32 pos_p1, WORD32 pos_p2, WORD32 pos_p3, + WORD32 pos_p4, WORD32 num_bits_pos) { + WORD32 nb_pos; + WORD32 index; + nb_pos = (1 << (num_bits_pos - 1)); + + if (((pos_p1 ^ pos_p2) & nb_pos) == 0) { + index = iusace_acelp_quant_2p_2n1bits(pos_p1, pos_p2, (num_bits_pos - 1)); + index += (pos_p1 & nb_pos) << num_bits_pos; + index += iusace_acelp_quant_2p_2n1bits(pos_p3, pos_p4, num_bits_pos) << (2 * num_bits_pos); + } else if (((pos_p1 ^ pos_p3) & nb_pos) == 0) { + index = iusace_acelp_quant_2p_2n1bits(pos_p1, pos_p3, (num_bits_pos - 1)); + index += (pos_p1 & nb_pos) << num_bits_pos; + index += iusace_acelp_quant_2p_2n1bits(pos_p2, pos_p4, num_bits_pos) << (2 * num_bits_pos); + } else { + index = iusace_acelp_quant_2p_2n1bits(pos_p2, pos_p3, (num_bits_pos - 1)); + index += (pos_p2 & nb_pos) << num_bits_pos; + index += iusace_acelp_quant_2p_2n1bits(pos_p1, pos_p4, num_bits_pos) << (2 * num_bits_pos); + } + return (index); +} + +static WORD32 iusace_acelp_quant_4p_4nbits(WORD32 *pos_pulses, WORD32 num_bits_pos) { + WORD32 i, j, k, nb_pos, n_1; + WORD32 pos_a[4], pos_b[4]; + WORD32 index = 0; + n_1 = num_bits_pos - 1; + nb_pos = (1 << n_1); + i = 0; + j = 0; + for (k = 0; k < 4; k++) { + if ((pos_pulses[k] & nb_pos) == 0) { + pos_a[i++] = pos_pulses[k]; + } else { + pos_b[j++] = pos_pulses[k]; + } + } + switch (i) { + case 0: + index = 1 << ((4 * num_bits_pos) - 3); + index += iusace_acelp_quant_4p_4n1bits(pos_b[0], pos_b[1], pos_b[2], pos_b[3], n_1); + break; + case 1: + index = iusace_acelp_quant_1p_n1bits(pos_a[0], n_1) << ((3 * n_1) + 1); + index += iusace_acelp_quant_3p_3n1bits(pos_b[0], pos_b[1], pos_b[2], n_1); + break; + case 2: + index = iusace_acelp_quant_2p_2n1bits(pos_a[0], pos_a[1], n_1) << ((2 * n_1) + 1); + index += iusace_acelp_quant_2p_2n1bits(pos_b[0], pos_b[1], n_1); + break; + case 3: + index = iusace_acelp_quant_3p_3n1bits(pos_a[0], pos_a[1], pos_a[2], n_1) << num_bits_pos; + index += iusace_acelp_quant_1p_n1bits(pos_b[0], n_1); + break; + case 4: + index = iusace_acelp_quant_4p_4n1bits(pos_a[0], pos_a[1], pos_a[2], pos_a[3], n_1); + break; + } + index += (i & 3) << ((4 * num_bits_pos) - 2); + return (index); +} + +static WORD32 iusace_acelp_quant_5p_5nbits(WORD32 *pos_pulses, WORD32 num_bits_pos) { + WORD32 i, j, k, nb_pos, n_1; + WORD32 pos_a[5], pos_b[5]; + WORD32 index = 0; + n_1 = num_bits_pos - 1; + nb_pos = (1 << n_1); + i = 0; + j = 0; + for (k = 0; k < 5; k++) { + if ((pos_pulses[k] & nb_pos) == 0) { + pos_a[i++] = pos_pulses[k]; + } else { + pos_b[j++] = pos_pulses[k]; + } + } + switch (i) { + case 0: + index = 1 << ((5 * num_bits_pos) - 1); + index += iusace_acelp_quant_3p_3n1bits(pos_b[0], pos_b[1], pos_b[2], n_1) + << ((2 * num_bits_pos) + 1); + index += iusace_acelp_quant_2p_2n1bits(pos_b[3], pos_b[4], num_bits_pos); + break; + case 1: + index = 1 << ((5 * num_bits_pos) - 1); + index += iusace_acelp_quant_3p_3n1bits(pos_b[0], pos_b[1], pos_b[2], n_1) + << ((2 * num_bits_pos) + 1); + index += iusace_acelp_quant_2p_2n1bits(pos_b[3], pos_a[0], num_bits_pos); + break; + case 2: + index = 1 << ((5 * num_bits_pos) - 1); + index += iusace_acelp_quant_3p_3n1bits(pos_b[0], pos_b[1], pos_b[2], n_1) + << ((2 * num_bits_pos) + 1); + index += iusace_acelp_quant_2p_2n1bits(pos_a[0], pos_a[1], num_bits_pos); + break; + case 3: + index = iusace_acelp_quant_3p_3n1bits(pos_a[0], pos_a[1], pos_a[2], n_1) + << ((2 * num_bits_pos) + 1); + index += iusace_acelp_quant_2p_2n1bits(pos_b[0], pos_b[1], num_bits_pos); + break; + case 4: + index = iusace_acelp_quant_3p_3n1bits(pos_a[0], pos_a[1], pos_a[2], n_1) + << ((2 * num_bits_pos) + 1); + index += iusace_acelp_quant_2p_2n1bits(pos_a[3], pos_b[0], num_bits_pos); + break; + case 5: + index = iusace_acelp_quant_3p_3n1bits(pos_a[0], pos_a[1], pos_a[2], n_1) + << ((2 * num_bits_pos) + 1); + index += iusace_acelp_quant_2p_2n1bits(pos_a[3], pos_a[4], num_bits_pos); + break; + } + return (index); +} + +static WORD32 iusace_acelp_quant_6p_6n_2bits(WORD32 *pos_pulses, WORD32 num_bits_pos) { + WORD32 i, j, k, nb_pos, n_1; + WORD32 pos_a[6], pos_b[6]; + WORD32 index = 0; + n_1 = num_bits_pos - 1; + nb_pos = 1 << n_1; + i = 0; + j = 0; + for (k = 0; k < 6; k++) { + if ((pos_pulses[k] & nb_pos) == 0) { + pos_a[i++] = pos_pulses[k]; + } else { + pos_b[j++] = pos_pulses[k]; + } + } + + switch (i) { + case 0: + index = 1 << ((6 * num_bits_pos) - 5); + index += iusace_acelp_quant_5p_5nbits(pos_b, n_1) << num_bits_pos; + index += iusace_acelp_quant_1p_n1bits(pos_b[5], n_1); + break; + case 1: + index = 1 << ((6 * num_bits_pos) - 5); + index += iusace_acelp_quant_5p_5nbits(pos_b, n_1) << num_bits_pos; + index += iusace_acelp_quant_1p_n1bits(pos_a[0], n_1); + break; + case 2: + index = 1 << ((6 * num_bits_pos) - 5); + index += iusace_acelp_quant_4p_4nbits(pos_b, n_1) << ((2 * n_1) + 1); + index += iusace_acelp_quant_2p_2n1bits(pos_a[0], pos_a[1], n_1); + break; + case 3: + index = iusace_acelp_quant_3p_3n1bits(pos_a[0], pos_a[1], pos_a[2], n_1) << ((3 * n_1) + 1); + index += iusace_acelp_quant_3p_3n1bits(pos_b[0], pos_b[1], pos_b[2], n_1); + break; + case 4: + i = 2; + index = iusace_acelp_quant_4p_4nbits(pos_a, n_1) << ((2 * n_1) + 1); + index += iusace_acelp_quant_2p_2n1bits(pos_b[0], pos_b[1], n_1); + break; + case 5: + i = 1; + index = iusace_acelp_quant_5p_5nbits(pos_a, n_1) << num_bits_pos; + index += iusace_acelp_quant_1p_n1bits(pos_b[0], n_1); + break; + case 6: + i = 0; + index = iusace_acelp_quant_5p_5nbits(pos_a, n_1) << num_bits_pos; + index += iusace_acelp_quant_1p_n1bits(pos_a[5], n_1); + break; + } + index += (i & 3) << ((6 * num_bits_pos) - 4); + return (index); +} + +VOID iusace_acelp_tgt_ir_corr(FLOAT32 *x, FLOAT32 *ir_wsyn, FLOAT32 *corr_out) { + WORD16 i, j; + FLOAT32 sum; + for (i = 0; i < LEN_SUBFR; i++) { + sum = 0.0F; + for (j = i; j < LEN_SUBFR; j++) { + sum += x[j] * ir_wsyn[j - i]; + } + corr_out[i] = sum; + } +} + +FLOAT32 iusace_acelp_tgt_cb_corr2(FLOAT32 *xn, FLOAT32 *y1, FLOAT32 *corr_out) { + FLOAT32 gain; + FLOAT32 t0, t1; + WORD16 i; + t0 = xn[0] * y1[0]; + t1 = y1[0] * y1[0]; + for (i = 1; i < LEN_SUBFR; i += 7) { + t0 += xn[i] * y1[i]; + t1 += y1[i] * y1[i]; + t0 += xn[i + 1] * y1[i + 1]; + t1 += y1[i + 1] * y1[i + 1]; + t0 += xn[i + 2] * y1[i + 2]; + t1 += y1[i + 2] * y1[i + 2]; + t0 += xn[i + 3] * y1[i + 3]; + t1 += y1[i + 3] * y1[i + 3]; + t0 += xn[i + 4] * y1[i + 4]; + t1 += y1[i + 4] * y1[i + 4]; + t0 += xn[i + 5] * y1[i + 5]; + t1 += y1[i + 5] * y1[i + 5]; + t0 += xn[i + 6] * y1[i + 6]; + t1 += y1[i + 6] * y1[i + 6]; + } + corr_out[0] = t1; + corr_out[1] = -2.0F * t0 + 0.01F; + + if (t1) { + gain = t0 / t1; + } else { + gain = 1.0F; + } + if (gain < 0.0) { + gain = 0.0; + } else if (gain > 1.2F) { + gain = 1.2F; + } + return gain; +} + +VOID iusace_acelp_tgt_cb_corr1(FLOAT32 *xn, FLOAT32 *y1, FLOAT32 *y2, FLOAT32 *corr_out) { + WORD32 i; + FLOAT32 temp1, temp2, temp3; + temp1 = 0.01F + y2[0] * y2[0]; + temp2 = 0.01F + xn[0] * y2[0]; + temp3 = 0.01F + y1[0] * y2[0]; + temp1 += y2[1] * y2[1]; + temp2 += xn[1] * y2[1]; + temp3 += y1[1] * y2[1]; + temp1 += y2[2] * y2[2]; + temp2 += xn[2] * y2[2]; + temp3 += y1[2] * y2[2]; + temp1 += y2[3] * y2[3]; + temp2 += xn[3] * y2[3]; + temp3 += y1[3] * y2[3]; + for (i = 4; i < LEN_SUBFR; i += 6) { + temp1 += y2[i] * y2[i]; + temp2 += xn[i] * y2[i]; + temp3 += y1[i] * y2[i]; + temp1 += y2[i + 1] * y2[i + 1]; + temp2 += xn[i + 1] * y2[i + 1]; + temp3 += y1[i + 1] * y2[i + 1]; + temp1 += y2[i + 2] * y2[i + 2]; + temp2 += xn[i + 2] * y2[i + 2]; + temp3 += y1[i + 2] * y2[i + 2]; + temp1 += y2[i + 3] * y2[i + 3]; + temp2 += xn[i + 3] * y2[i + 3]; + temp3 += y1[i + 3] * y2[i + 3]; + temp1 += y2[i + 4] * y2[i + 4]; + temp2 += xn[i + 4] * y2[i + 4]; + temp3 += y1[i + 4] * y2[i + 4]; + temp1 += y2[i + 5] * y2[i + 5]; + temp2 += xn[i + 5] * y2[i + 5]; + temp3 += y1[i + 5] * y2[i + 5]; + } + corr_out[2] = temp1; + corr_out[3] = -2.0F * temp2; + corr_out[4] = 2.0F * temp3; +} + +VOID iusace_acelp_cb_target_update(FLOAT32 *x, FLOAT32 *new_x, FLOAT32 *cb_vec, FLOAT32 gain) { + WORD16 i; + for (i = 0; i < LEN_SUBFR; i++) { + new_x[i] = x[i] - gain * cb_vec[i]; + } +} + +VOID iusace_acelp_cb_exc(FLOAT32 *corr_input, FLOAT32 *lp_residual, FLOAT32 *ir_wsyn, + WORD16 *alg_cb_exc_out, FLOAT32 *filt_cb_exc, WORD32 num_bits_cb, + WORD32 *acelp_param_out, FLOAT32 *scratch_acelp_ir_buf) { + FLOAT32 sign[LEN_SUBFR], vec[LEN_SUBFR]; + FLOAT32 corr_x[16], corr_y[16]; + FLOAT32 *ir_buf = scratch_acelp_ir_buf; + FLOAT32 corr_ir[4][16]; + FLOAT32 corr_p1p2[4][256]; + FLOAT32 dn2[LEN_SUBFR]; + WORD32 pulse_pos[NPMAXPT * 4] = {0}; + WORD32 codvec[MAX_NUM_PULSES] = {0}; + WORD32 num_pulse_position[10] = {0}; + WORD32 pos_max[4]; + WORD32 dn2_pos[8 * 4]; + UWORD8 ipos[MAX_NUM_PULSES] = {0}; + WORD32 i, j, k, st, pos = 0, index, track, num_pulses = 0, num_iter = 4; + WORD32 l_index; + FLOAT32 psk, ps, alpk, alp = 0.0F; + FLOAT32 val; + FLOAT32 s, cor; + FLOAT32 *p0, *p1, *p2, *p3, *psign; + FLOAT32 *p1_ir_buf, *p2_ir_buf, *p3_ir_buf, *p4_ir_buf, *ir_sign_inv; + switch (num_bits_cb) { + case ACELP_NUM_BITS_20: + num_iter = 4; + alp = 2.0; + num_pulses = 4; + num_pulse_position[0] = 4; + num_pulse_position[1] = 8; + break; + case ACELP_NUM_BITS_28: + num_iter = 4; + alp = 1.5; + num_pulses = 6; + num_pulse_position[0] = 4; + num_pulse_position[1] = 8; + num_pulse_position[2] = 8; + break; + + case ACELP_NUM_BITS_36: + num_iter = 4; + alp = 1.0; + num_pulses = 8; + num_pulse_position[0] = 4; + num_pulse_position[1] = 8; + num_pulse_position[2] = 8; + break; + case ACELP_NUM_BITS_44: + num_iter = 4; + alp = 1.0; + num_pulses = 10; + num_pulse_position[0] = 4; + num_pulse_position[1] = 6; + num_pulse_position[2] = 8; + num_pulse_position[3] = 8; + break; + case ACELP_NUM_BITS_52: + num_iter = 4; + alp = 1.0; + num_pulses = 12; + num_pulse_position[0] = 4; + num_pulse_position[1] = 6; + num_pulse_position[2] = 8; + num_pulse_position[3] = 8; + break; + case ACELP_NUM_BITS_64: + num_iter = 3; + alp = 0.8F; + num_pulses = 16; + num_pulse_position[0] = 4; + num_pulse_position[1] = 4; + num_pulse_position[2] = 6; + num_pulse_position[3] = 6; + num_pulse_position[4] = 8; + num_pulse_position[5] = 8; + break; + } + + val = (lp_residual[0] * lp_residual[0]) + 1.0F; + cor = (corr_input[0] * corr_input[0]) + 1.0F; + for (i = 1; i < LEN_SUBFR; i += 7) { + val += (lp_residual[i] * lp_residual[i]); + cor += (corr_input[i] * corr_input[i]); + val += (lp_residual[i + 1] * lp_residual[i + 1]); + cor += (corr_input[i + 1] * corr_input[i + 1]); + val += (lp_residual[i + 2] * lp_residual[i + 2]); + cor += (corr_input[i + 2] * corr_input[i + 2]); + val += (lp_residual[i + 3] * lp_residual[i + 3]); + cor += (corr_input[i + 3] * corr_input[i + 3]); + val += (lp_residual[i + 4] * lp_residual[i + 4]); + cor += (corr_input[i + 4] * corr_input[i + 4]); + val += (lp_residual[i + 5] * lp_residual[i + 5]); + cor += (corr_input[i + 5] * corr_input[i + 5]); + val += (lp_residual[i + 6] * lp_residual[i + 6]); + cor += (corr_input[i + 6] * corr_input[i + 6]); + } + s = (FLOAT32)sqrt(cor / val); + for (j = 0; j < LEN_SUBFR; j++) { + cor = (s * lp_residual[j]) + (alp * corr_input[j]); + if (cor >= 0.0F) { + sign[j] = 1.0F; + vec[j] = -1.0F; + dn2[j] = cor; + } else { + sign[j] = -1.0F; + vec[j] = 1.0F; + corr_input[j] = -corr_input[j]; + dn2[j] = -cor; + } + } + for (i = 0; i < 4; i++) { + for (k = 0; k < 8; k++) { + ps = -1; + for (j = i; j < LEN_SUBFR; j += 4) { + if (dn2[j] > ps) { + ps = dn2[j]; + pos = j; + } + } + dn2[pos] = (FLOAT32)k - 8; + dn2_pos[i * 8 + k] = pos; + } + pos_max[i] = dn2_pos[i * 8]; + } + + memset(ir_buf, 0, LEN_SUBFR * sizeof(FLOAT32)); + memset(ir_buf + (2 * LEN_SUBFR), 0, LEN_SUBFR * sizeof(FLOAT32)); + p1_ir_buf = ir_buf + LEN_SUBFR; + ir_sign_inv = ir_buf + (3 * LEN_SUBFR); + memcpy(p1_ir_buf, ir_wsyn, LEN_SUBFR * sizeof(FLOAT32)); + ir_sign_inv[0] = -p1_ir_buf[0]; + ir_sign_inv[1] = -p1_ir_buf[1]; + ir_sign_inv[2] = -p1_ir_buf[2]; + ir_sign_inv[3] = -p1_ir_buf[3]; + for (i = 4; i < LEN_SUBFR; i += 6) { + ir_sign_inv[i] = -p1_ir_buf[i]; + ir_sign_inv[i + 1] = -p1_ir_buf[i + 1]; + ir_sign_inv[i + 2] = -p1_ir_buf[i + 2]; + ir_sign_inv[i + 3] = -p1_ir_buf[i + 3]; + ir_sign_inv[i + 4] = -p1_ir_buf[i + 4]; + ir_sign_inv[i + 5] = -p1_ir_buf[i + 5]; + } + + p0 = &corr_ir[0][16 - 1]; + p1 = &corr_ir[1][16 - 1]; + p2 = &corr_ir[2][16 - 1]; + p3 = &corr_ir[3][16 - 1]; + p2_ir_buf = p1_ir_buf; + cor = 0.0F; + for (i = 0; i < 16; i++) { + cor += (*p2_ir_buf) * (*p2_ir_buf); + p2_ir_buf++; + *p3-- = cor * 0.5F; + cor += (*p2_ir_buf) * (*p2_ir_buf); + p2_ir_buf++; + *p2-- = cor * 0.5F; + cor += (*p2_ir_buf) * (*p2_ir_buf); + p2_ir_buf++; + *p1-- = cor * 0.5F; + cor += (*p2_ir_buf) * (*p2_ir_buf); + p2_ir_buf++; + *p0-- = cor * 0.5F; + } + pos = 256 - 1; + p4_ir_buf = p1_ir_buf + 1; + for (k = 0; k < 16; k++) { + p3 = &corr_p1p2[2][pos]; + p2 = &corr_p1p2[1][pos]; + p1 = &corr_p1p2[0][pos]; + if (k == 15) { + p0 = &corr_p1p2[3][pos - 15]; + } else { + p0 = &corr_p1p2[3][pos - 16]; + } + cor = 0.0F; + p2_ir_buf = p1_ir_buf; + p3_ir_buf = p4_ir_buf; + for (i = k + 1; i < 16; i++) { + cor += (*p2_ir_buf) * (*p3_ir_buf); + p2_ir_buf++; + p3_ir_buf++; + *p3 = cor; + cor += (*p2_ir_buf) * (*p3_ir_buf); + p2_ir_buf++; + p3_ir_buf++; + *p2 = cor; + cor += (*p2_ir_buf) * (*p3_ir_buf); + p2_ir_buf++; + p3_ir_buf++; + *p1 = cor; + cor += (*p2_ir_buf) * (*p3_ir_buf); + p2_ir_buf++; + p3_ir_buf++; + *p0 = cor; + p3 -= (16 + 1); + p2 -= (16 + 1); + p1 -= (16 + 1); + p0 -= (16 + 1); + } + cor += (*p2_ir_buf) * (*p3_ir_buf); + p2_ir_buf++; + p3_ir_buf++; + *p3 = cor; + cor += (*p2_ir_buf) * (*p3_ir_buf); + p2_ir_buf++; + p3_ir_buf++; + *p2 = cor; + cor += (*p2_ir_buf) * (*p3_ir_buf); + p2_ir_buf++; + p3_ir_buf++; + *p1 = cor; + pos -= 16; + p4_ir_buf += 4; + } + pos = 256 - 1; + p4_ir_buf = p1_ir_buf + 3; + for (k = 0; k < 16; k++) { + p3 = &corr_p1p2[3][pos]; + p2 = &corr_p1p2[2][pos - 1]; + p1 = &corr_p1p2[1][pos - 1]; + p0 = &corr_p1p2[0][pos - 1]; + cor = 0.0F; + p2_ir_buf = p1_ir_buf; + p3_ir_buf = p4_ir_buf; + for (i = k + 1; i < 16; i++) { + cor += (*p2_ir_buf) * (*p3_ir_buf); + p2_ir_buf++; + p3_ir_buf++; + *p3 = cor; + cor += (*p2_ir_buf) * (*p3_ir_buf); + p2_ir_buf++; + p3_ir_buf++; + *p2 = cor; + cor += (*p2_ir_buf) * (*p3_ir_buf); + p2_ir_buf++; + p3_ir_buf++; + *p1 = cor; + cor += (*p2_ir_buf) * (*p3_ir_buf); + p2_ir_buf++; + p3_ir_buf++; + *p0 = cor; + p3 -= (16 + 1); + p2 -= (16 + 1); + p1 -= (16 + 1); + p0 -= (16 + 1); + } + cor += (*p2_ir_buf) * (*p3_ir_buf); + p2_ir_buf++; + p3_ir_buf++; + *p3 = cor; + pos--; + p4_ir_buf += 4; + } + + p0 = &corr_p1p2[0][0]; + for (k = 0; k < 4; k++) { + for (i = k; i < LEN_SUBFR; i += 4) { + psign = sign; + if (psign[i] < 0.0F) { + psign = vec; + } + j = (k + 1) % 4; + p0[0] = p0[0] * psign[j]; + p0[1] = p0[1] * psign[j + 4]; + p0[2] = p0[2] * psign[j + 8]; + p0[3] = p0[3] * psign[j + 12]; + p0[4] = p0[4] * psign[j + 16]; + p0[5] = p0[5] * psign[j + 20]; + p0[6] = p0[6] * psign[j + 24]; + p0[7] = p0[7] * psign[j + 28]; + p0[8] = p0[8] * psign[j + 32]; + p0[9] = p0[9] * psign[j + 36]; + p0[10] = p0[10] * psign[j + 40]; + p0[11] = p0[11] * psign[j + 44]; + p0[12] = p0[12] * psign[j + 48]; + p0[13] = p0[13] * psign[j + 52]; + p0[14] = p0[14] * psign[j + 56]; + p0[15] = p0[15] * psign[j + 60]; + p0 += 16; + } + } + psk = -1.0; + alpk = 1.0; + for (k = 0; k < num_iter; k++) { + for (i = 0; i < num_pulses - (num_pulses % 3); i += 3) { + ipos[i] = iusace_acelp_ipos[(k * 4) + i]; + ipos[i + 1] = iusace_acelp_ipos[(k * 4) + i + 1]; + ipos[i + 2] = iusace_acelp_ipos[(k * 4) + i + 2]; + } + for (; i < num_pulses; i++) { + ipos[i] = iusace_acelp_ipos[(k * 4) + i]; + } + + if ((num_bits_cb == 20) | (num_bits_cb == 28) | (num_bits_cb == 12) | (num_bits_cb == 16)) { + pos = 0; + ps = 0.0F; + alp = 0.0F; + memset(vec, 0, LEN_SUBFR * sizeof(FLOAT32)); + if (num_bits_cb == 28) { + ipos[4] = 0; + ipos[5] = 1; + } + + if (num_bits_cb == 16) { + ipos[0] = 0; + ipos[1] = 2; + ipos[2] = 1; + ipos[3] = 3; + } + } else if ((num_bits_cb == 36) | (num_bits_cb == 44)) { + pos = 2; + pulse_pos[0] = pos_max[ipos[0]]; + pulse_pos[1] = pos_max[ipos[1]]; + ps = corr_input[pulse_pos[0]] + corr_input[pulse_pos[1]]; + alp = corr_ir[ipos[0]][pulse_pos[0] >> 2] + corr_ir[ipos[1]][pulse_pos[1] >> 2] + + corr_p1p2[ipos[0]][((pulse_pos[0] >> 2) << 4) + (pulse_pos[1] >> 2)]; + if (sign[pulse_pos[0]] < 0.0) { + p0 = ir_sign_inv - pulse_pos[0]; + } else { + p0 = p1_ir_buf - pulse_pos[0]; + } + if (sign[pulse_pos[1]] < 0.0) { + p1 = ir_sign_inv - pulse_pos[1]; + } else { + p1 = p1_ir_buf - pulse_pos[1]; + } + vec[0] = p0[0] + p1[0]; + vec[1] = p0[1] + p1[1]; + vec[2] = p0[2] + p1[2]; + vec[3] = p0[3] + p1[3]; + for (i = 4; i < LEN_SUBFR; i += 6) { + vec[i] = p0[i] + p1[i]; + vec[i + 1] = p0[i + 1] + p1[i + 1]; + vec[i + 2] = p0[i + 2] + p1[i + 2]; + vec[i + 3] = p0[i + 3] + p1[i + 3]; + vec[i + 4] = p0[i + 4] + p1[i + 4]; + vec[i + 5] = p0[i + 5] + p1[i + 5]; + } + if (num_bits_cb == 44) { + ipos[8] = 0; + ipos[9] = 1; + } + } else { + pos = 4; + pulse_pos[0] = pos_max[ipos[0]]; + pulse_pos[1] = pos_max[ipos[1]]; + pulse_pos[2] = pos_max[ipos[2]]; + pulse_pos[3] = pos_max[ipos[3]]; + ps = corr_input[pulse_pos[0]] + corr_input[pulse_pos[1]] + corr_input[pulse_pos[2]] + + corr_input[pulse_pos[3]]; + p0 = p1_ir_buf - pulse_pos[0]; + if (sign[pulse_pos[0]] < 0.0) { + p0 = ir_sign_inv - pulse_pos[0]; + } + p1 = p1_ir_buf - pulse_pos[1]; + if (sign[pulse_pos[1]] < 0.0) { + p1 = ir_sign_inv - pulse_pos[1]; + } + p2 = p1_ir_buf - pulse_pos[2]; + if (sign[pulse_pos[2]] < 0.0) { + p2 = ir_sign_inv - pulse_pos[2]; + } + p3 = p1_ir_buf - pulse_pos[3]; + if (sign[pulse_pos[3]] < 0.0) { + p3 = ir_sign_inv - pulse_pos[3]; + } + vec[0] = p0[0] + p1[0] + p2[0] + p3[0]; + for (i = 1; i < LEN_SUBFR; i += 3) { + vec[i] = p0[i] + p1[i] + p2[i] + p3[i]; + vec[i + 1] = p0[i + 1] + p1[i + 1] + p2[i + 1] + p3[i + 1]; + vec[i + 2] = p0[i + 2] + p1[i + 2] + p2[i + 2] + p3[i + 2]; + } + alp = 0.0F; + alp += vec[0] * vec[0] + vec[1] * vec[1]; + alp += vec[2] * vec[2] + vec[3] * vec[3]; + for (i = 4; i < LEN_SUBFR; i += 6) { + alp += vec[i] * vec[i]; + alp += vec[i + 1] * vec[i + 1]; + alp += vec[i + 2] * vec[i + 2]; + alp += vec[i + 3] * vec[i + 3]; + alp += vec[i + 4] * vec[i + 4]; + alp += vec[i + 5] * vec[i + 5]; + } + alp *= 0.5F; + if (num_bits_cb == 72) { + ipos[16] = 0; + ipos[17] = 1; + } + } + + for (j = pos, st = 0; j < num_pulses; j += 2, st++) { + if ((num_pulses - j) >= 2) { + iusace_acelp_ir_vec_corr1(p1_ir_buf, vec, ipos[j], sign, corr_ir, corr_x, dn2_pos, + num_pulse_position[st]); + iusace_acelp_ir_vec_corr2(p1_ir_buf, vec, ipos[j + 1], sign, corr_ir, corr_y); + + iusace_acelp_get_2p_pos(num_pulse_position[st], ipos[j], ipos[j + 1], &ps, &alp, + &pulse_pos[j], &pulse_pos[j + 1], corr_input, dn2_pos, corr_x, + corr_y, corr_p1p2); + } else { + iusace_acelp_ir_vec_corr2(p1_ir_buf, vec, ipos[j], sign, corr_ir, corr_x); + iusace_acelp_ir_vec_corr2(p1_ir_buf, vec, ipos[j + 1], sign, corr_ir, corr_y); + iusace_acelp_get_1p_pos(ipos[j], ipos[j + 1], &ps, &alp, &pulse_pos[j], corr_input, + corr_x, corr_y); + } + if (j < (num_pulses - 2)) { + p0 = p1_ir_buf - pulse_pos[j]; + if (sign[pulse_pos[j]] < 0.0) { + p0 = ir_sign_inv - pulse_pos[j]; + } + p1 = p1_ir_buf - pulse_pos[j + 1]; + if (sign[pulse_pos[j + 1]] < 0.0) { + p1 = ir_sign_inv - pulse_pos[j + 1]; + } + vec[0] += p0[0] + p1[0]; + vec[1] += p0[1] + p1[1]; + vec[2] += p0[2] + p1[2]; + vec[3] += p0[3] + p1[3]; + for (i = 4; i < LEN_SUBFR; i += 6) { + vec[i] += p0[i] + p1[i]; + vec[i + 1] += p0[i + 1] + p1[i + 1]; + vec[i + 2] += p0[i + 2] + p1[i + 2]; + vec[i + 3] += p0[i + 3] + p1[i + 3]; + vec[i + 4] += p0[i + 4] + p1[i + 4]; + vec[i + 5] += p0[i + 5] + p1[i + 5]; + } + } + } + ps = ps * ps; + s = (alpk * ps) - (psk * alp); + if (s > 0.0F) { + psk = ps; + alpk = alp; + memcpy(codvec, pulse_pos, num_pulses * sizeof(WORD32)); + } + } + + memset(alg_cb_exc_out, 0, LEN_SUBFR * sizeof(WORD16)); + memset(filt_cb_exc, 0, LEN_SUBFR * sizeof(FLOAT32)); + memset(pulse_pos, 0xffffffff, NPMAXPT * 4 * sizeof(WORD32)); + for (k = 0; k < num_pulses; k++) { + i = codvec[k]; + val = sign[i]; + index = i / 4; + track = i % 4; + if (val > 0) { + alg_cb_exc_out[i] += 512; + codvec[k] += (2 * LEN_SUBFR); + } else { + alg_cb_exc_out[i] -= 512; + index += 16; + } + i = track * NPMAXPT; + while (pulse_pos[i] >= 0) { + i++; + } + pulse_pos[i] = index; + p0 = ir_sign_inv - codvec[k]; + filt_cb_exc[0] += p0[0]; + for (i = 1; i < LEN_SUBFR; i += 3) { + filt_cb_exc[i] += p0[i]; + filt_cb_exc[i + 1] += p0[i + 1]; + filt_cb_exc[i + 2] += p0[i + 2]; + } + } + + if (num_bits_cb == ACELP_NUM_BITS_20) { + for (track = 0; track < 4; track++) { + k = track * NPMAXPT; + acelp_param_out[track] = iusace_acelp_quant_1p_n1bits(pulse_pos[k], 4); + } + } else if (num_bits_cb == ACELP_NUM_BITS_28) { + for (track = 0; track < (4 - 2); track++) { + k = track * NPMAXPT; + acelp_param_out[track] = iusace_acelp_quant_2p_2n1bits(pulse_pos[k], pulse_pos[k + 1], 4); + } + for (track = 2; track < 4; track++) { + k = track * NPMAXPT; + acelp_param_out[track] = iusace_acelp_quant_1p_n1bits(pulse_pos[k], 4); + } + } else if (num_bits_cb == ACELP_NUM_BITS_36) { + for (track = 0; track < 4; track++) { + k = track * NPMAXPT; + acelp_param_out[track] = iusace_acelp_quant_2p_2n1bits(pulse_pos[k], pulse_pos[k + 1], 4); + } + } else if (num_bits_cb == ACELP_NUM_BITS_44) { + for (track = 0; track < (4 - 2); track++) { + k = track * NPMAXPT; + acelp_param_out[track] = + iusace_acelp_quant_3p_3n1bits(pulse_pos[k], pulse_pos[k + 1], pulse_pos[k + 2], 4); + } + for (track = 2; track < 4; track++) { + k = track * NPMAXPT; + acelp_param_out[track] = iusace_acelp_quant_2p_2n1bits(pulse_pos[k], pulse_pos[k + 1], 4); + } + } else if (num_bits_cb == ACELP_NUM_BITS_52) { + for (track = 0; track < 4; track++) { + k = track * NPMAXPT; + acelp_param_out[track] = + iusace_acelp_quant_3p_3n1bits(pulse_pos[k], pulse_pos[k + 1], pulse_pos[k + 2], 4); + } + } else if (num_bits_cb == ACELP_NUM_BITS_64) { + for (track = 0; track < 4; track++) { + k = track * NPMAXPT; + l_index = iusace_acelp_quant_4p_4nbits(&pulse_pos[k], 4); + acelp_param_out[track] = ((l_index >> 14) & 3); + acelp_param_out[track + 4] = (l_index & 0x3FFF); + } + } else if (num_bits_cb == ACELP_NUM_BITS_72) { + for (track = 0; track < (4 - 2); track++) { + k = track * NPMAXPT; + l_index = iusace_acelp_quant_5p_5nbits(&pulse_pos[k], 4); + acelp_param_out[track] = ((l_index >> 10) & 0x03FF); + acelp_param_out[track + 4] = (l_index & 0x03FF); + } + for (track = 2; track < 4; track++) { + k = track * NPMAXPT; + l_index = iusace_acelp_quant_4p_4nbits(&pulse_pos[k], 4); + acelp_param_out[track] = ((l_index >> 14) & 3); + acelp_param_out[track + 4] = (l_index & 0x3FFF); + } + } else if (num_bits_cb == ACELP_NUM_BITS_88) { + for (track = 0; track < 4; track++) { + k = track * NPMAXPT; + l_index = iusace_acelp_quant_6p_6n_2bits(&pulse_pos[k], 4); + acelp_param_out[track] = ((l_index >> 11) & 0x07FF); + acelp_param_out[track + 4] = (l_index & 0x07FF); + } + } + return; +} + +VOID iusace_acelp_ltpred_cb_exc(FLOAT32 *exc, WORD32 t0, WORD32 t0_frac, WORD32 len_subfrm) { + WORD32 i, j; + FLOAT32 s, *x0, *x1, *x2; + const FLOAT32 *c1, *c2; + + x0 = &exc[-t0]; + t0_frac = -t0_frac; + if (t0_frac < 0) { + t0_frac += T_UP_SAMP; + x0--; + } + for (j = 0; j < len_subfrm; j++) { + x1 = x0++; + x2 = x1 + 1; + c1 = &iusace_res_interp_filter1_4[t0_frac]; + c2 = &iusace_res_interp_filter1_4[T_UP_SAMP - t0_frac]; + s = 0.0; + for (i = 0; i < INTER_LP_FIL_ORDER; i++, c1 += T_UP_SAMP, c2 += T_UP_SAMP) { + s += (*x1--) * (*c1) + (*x2++) * (*c2); + } + exc[j] = s; + } +} + +VOID iusace_acelp_quant_gain(FLOAT32 *code, FLOAT32 *pitch_gain, FLOAT32 *code_gain, + FLOAT32 *tgt_cb_corr_data, FLOAT32 mean_energy, WORD32 *qunt_idx) { + WORD32 i, indice = 0, min_pitch_idx; + FLOAT32 ener_code, pred_code_gain; + FLOAT32 dist, dist_min, g_pitch, g_code; + const FLOAT32 *p1_qua_gain_table, *p2_qua_gain_table; + + p1_qua_gain_table = iusace_acelp_quant_gain_table; + p2_qua_gain_table = (const FLOAT32 *)(iusace_acelp_quant_gain_table + ACELP_GAIN_TBL_OFFSET); + min_pitch_idx = 0; + g_pitch = *pitch_gain; + for (i = 0; i < ACELP_RANGE_GAIN_PT_IDX_SEARCH; i++, p2_qua_gain_table += 2) { + if (g_pitch > *p2_qua_gain_table) { + continue; + } + } + ener_code = 0.01F; + + for (i = 0; i < LEN_SUBFR; i++) { + ener_code += code[i] * code[i]; + } + + ener_code = (FLOAT32)(10.0 * log10(ener_code / (FLOAT32)LEN_SUBFR)); + pred_code_gain = mean_energy - ener_code; + pred_code_gain = (FLOAT32)pow(10.0, pred_code_gain / 20.0); + + dist_min = MAX_FLT_VAL; + p2_qua_gain_table = (const FLOAT32 *)(p1_qua_gain_table + min_pitch_idx * 2); + for (i = 0; i < ACELP_SEARCH_RANGE_QUANTIZER_IDX; i++) { + g_pitch = *p2_qua_gain_table++; + g_code = pred_code_gain * *p2_qua_gain_table++; + dist = g_pitch * g_pitch * tgt_cb_corr_data[0] + g_pitch * tgt_cb_corr_data[1] + + g_code * g_code * tgt_cb_corr_data[2] + g_code * tgt_cb_corr_data[3] + + g_pitch * g_code * tgt_cb_corr_data[4]; + if (dist < dist_min) { + dist_min = dist; + indice = i; + } + } + indice += min_pitch_idx; + *pitch_gain = p1_qua_gain_table[indice * 2]; + *code_gain = p1_qua_gain_table[indice * 2 + 1] * pred_code_gain; + *qunt_idx = indice; +} diff --git a/encoder/iusace_arith_enc.c b/encoder/iusace_arith_enc.c new file mode 100644 index 0000000..2f189d4 --- /dev/null +++ b/encoder/iusace_arith_enc.c @@ -0,0 +1,433 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include +#include +#include "ixheaac_type_def.h" +#include "ixheaace_adjust_threshold_data.h" +#include "iusace_bitbuffer.h" +#include "ixheaace_mps_common_define.h" + +/* DRC */ +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" +#include "impd_drc_uni_drc_eq.h" +#include "impd_drc_uni_drc_filter_bank.h" +#include "impd_drc_gain_enc.h" +#include "impd_drc_struct_def.h" + +#include "iusace_cnst.h" +#include "iusace_tns_usac.h" +#include "iusace_psy_mod.h" +#include "iusace_config.h" +#include "iusace_arith_enc.h" +#include "iusace_block_switch_const.h" +#include "iusace_rom.h" + +#define ARITH_ESCAPE (16) + +static VOID iusace_arith_map_context(WORD32 pres_n, WORD32 prev_n, WORD32 *ptr_c_prev, + WORD32 *ptr_c_pres, WORD32 arith_reset_flag) { + WORD32 i, k; + FLOAT32 ratio; + WORD32 c_prev[516]; + WORD32 c_pres[516]; + + if (arith_reset_flag) { + memset(ptr_c_pres, 0, 516 * sizeof(WORD32)); + memset(ptr_c_prev, 0, 516 * sizeof(WORD32)); + } else { + memcpy(&c_prev[2], &ptr_c_prev[2], (prev_n / 2 + 2) * sizeof(WORD32)); + memcpy(&c_pres[2], &ptr_c_pres[2], (prev_n / 2 + 2) * sizeof(WORD32)); + + ratio = (FLOAT32)(prev_n) / (FLOAT32)(pres_n); + for (i = 0; i < (pres_n / 2); i++) { + k = (WORD32)((FLOAT32)(i)*ratio); + ptr_c_pres[2 + i] = c_pres[2 + k]; + ptr_c_prev[2 + i] = c_prev[2 + k]; + } + + ptr_c_pres[(pres_n / 2) + 2] = c_pres[(prev_n / 2) + 2]; + ptr_c_pres[(pres_n / 2) + 3] = c_pres[(prev_n / 2) + 3]; + ptr_c_prev[(pres_n / 2) + 2] = c_prev[(prev_n / 2) + 2]; + ptr_c_prev[(pres_n / 2) + 3] = c_prev[(prev_n / 2) + 3]; + } + return; +} + +static WORD32 iusace_arith_get_state(WORD32 *c_pres, WORD32 *c_prev, WORD32 *s, WORD32 idx) { + WORD32 s_tmp = *s; + + s_tmp = s_tmp >> 4; + s_tmp = s_tmp + (c_prev[idx + 1] << 12); + s_tmp = (s_tmp & 0xFFF0) + c_pres[idx - 1]; + + *s = s_tmp; + + if (idx > 3) { + if ((c_pres[idx - 1] + c_pres[idx - 2] + c_pres[idx - 3]) < 5) { + return (s_tmp + 0x10000); + } + } + + return (s_tmp); +} + +static UWORD16 iusace_arith_get_pk(WORD32 c) { + WORD32 j; + WORD32 i, i_min, i_max; + + i_min = -1; + i_max = (sizeof(iusace_ari_lookup_m) / sizeof(iusace_ari_lookup_m[0])) - 1; + while ((i_max - i_min) > 1) { + i = i_min + ((i_max - i_min) / 2); + j = iusace_ari_hash_m[i]; + if (c < j) + i_max = i; + else if (c > j) + i_min = i; + else + return (iusace_ari_hash_m_lsb[i]); + } + + return (iusace_ari_lookup_m[i_max]); +} + +static VOID iusace_copy_bit_buf(ia_bit_buf_struct *it_bit_buff_dest, + ia_bit_buf_struct *it_bit_buff_src) { + if (it_bit_buff_src != NULL && it_bit_buff_dest != NULL) { + it_bit_buff_dest->cnt_bits = it_bit_buff_src->cnt_bits; + it_bit_buff_dest->ptr_write_next = it_bit_buff_src->ptr_write_next; + it_bit_buff_dest->write_position = it_bit_buff_src->write_position; + } + return; +} + +static WORD32 iusace_arith_encode_level2(ia_bit_buf_struct *pstr_it_bit_buff, WORD32 bp, + WORD32 *ptr_c_pres, WORD32 *ptr_c_prev, WORD32 *quant, + WORD32 n, WORD32 nt, WORD32 use_stop) { + WORD32 qs[32]; + iusace_state_arith as, as_stop; + + WORD32 a, b, a1, b1, m; + WORD32 s, t, i, l, lev, esc_nb; + UWORD16 pki; + WORD32 bp_start = bp; + WORD32 bp_stop = bp; + WORD32 stop = 0; + WORD32 sopt; + WORD32 a2, b2; + ia_bit_buf_struct it_bit_buff_temp; + memset(&it_bit_buff_temp, 0, sizeof(it_bit_buff_temp)); + iusace_copy_bit_buf(&it_bit_buff_temp, pstr_it_bit_buff); + + as.low = 0; + as.high = 65535; + as.value = 0; + + sopt = ptr_c_prev[0] << 12; + + for (i = 0; i < n; i++) { + if ((use_stop == 1 || use_stop == 2) && (stop == 0)) { + WORD32 j; + + stop = 1; + for (j = i; j < n; j++) { + if (quant[2 * j] != 0 || quant[2 * j + 1] != 0) { + stop = 0; + break; + } + } + + if (stop) { + s = iusace_arith_get_state(ptr_c_pres, ptr_c_prev, &sopt, i); + t = s & 0xFFFFF; + + pki = iusace_arith_get_pk(t); + + if (use_stop == 1) { + bp = iusace_arith_encode(pstr_it_bit_buff, bp, &as, ARITH_ESCAPE, iusace_ari_cf_m[pki]); + pki = iusace_arith_get_pk(t + (1 << 17)); + bp = iusace_arith_encode(pstr_it_bit_buff, bp, &as, 0, iusace_ari_cf_m[pki]); + + break; + } else { + bp_stop = bp; + as_stop.low = as.low; + as_stop.high = as.high; + as_stop.value = as.value; + + bp_stop = + iusace_arith_encode(NULL, bp_stop, &as_stop, ARITH_ESCAPE, iusace_ari_cf_m[pki]); + + pki = iusace_arith_get_pk(t + (1 << 17)); + bp_stop = iusace_arith_encode(NULL, bp_stop, &as_stop, (0), iusace_ari_cf_m[pki]); + } + } + } + s = iusace_arith_get_state(ptr_c_pres, ptr_c_prev, &sopt, i); + t = s & 0xFFFFF; + + a = quant[2 * i]; + b = quant[2 * i + 1]; + a1 = abs(a); + b1 = abs(b); + + ptr_c_pres[i] = a1 + b1 + 1; + if (ptr_c_pres[i] > 0xF) { + ptr_c_pres[i] = 0xF; + } + + lev = 0; + esc_nb = 0; + + while ((a1) > 3 || (b1) > 3) { + pki = iusace_arith_get_pk(t + (esc_nb << 17)); + + bp = iusace_arith_encode(pstr_it_bit_buff, bp, &as, ARITH_ESCAPE, iusace_ari_cf_m[pki]); + + qs[lev++] = (a1 & 1) | ((b1 & 1) << 1); + a1 >>= 1; + b1 >>= 1; + esc_nb++; + + if (esc_nb > 7) { + esc_nb = 7; + } + } + m = a1 + (b1 << 2); + pki = iusace_arith_get_pk(t + (esc_nb << 17)); + bp = iusace_arith_encode(pstr_it_bit_buff, bp, &as, m, iusace_ari_cf_m[pki]); + + a2 = a1; + b2 = b1; + + for (l = lev - 1; l >= 0; l--) { + WORD32 lsbidx = (a2 == 0) ? 1 : ((b2 == 0) ? 0 : 2); + bp = iusace_arith_encode(pstr_it_bit_buff, bp, &as, qs[l], iusace_ari_cf_r[lsbidx]); + + a2 = (a2 << 1) | (qs[l] & 1); + b2 = (b2 << 1) | ((qs[l] >> 1) & 1); + } + } + + if (use_stop == 2) { + bp = iusace_arith_done(pstr_it_bit_buff, bp, &as); + if (stop) { + bp_stop = iusace_arith_done(NULL, bp_stop, &as_stop); + + if (bp_stop < bp) { + iusace_copy_bit_buf(pstr_it_bit_buff, &it_bit_buff_temp); + bp = iusace_arith_encode_level2(pstr_it_bit_buff, bp_start, ptr_c_pres, ptr_c_prev, quant, + n, nt, 1); + } else { + iusace_copy_bit_buf(pstr_it_bit_buff, &it_bit_buff_temp); + bp = iusace_arith_encode_level2(pstr_it_bit_buff, bp_start, ptr_c_pres, ptr_c_prev, quant, + n, nt, 0); + } + } else { + iusace_copy_bit_buf(pstr_it_bit_buff, &it_bit_buff_temp); + bp = iusace_arith_encode_level2(pstr_it_bit_buff, bp_start, ptr_c_pres, ptr_c_prev, quant, + n, nt, 0); + } + } else { + bp = iusace_arith_done(pstr_it_bit_buff, bp, &as); + + for (; i < nt; i++) { + ptr_c_pres[i] = 1; + } + + for (i = 0; i < n; i++) { + if (quant[2 * i] != 0) { + if (quant[2 * i] > 0) { + iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); + bp++; + } else { + iusace_write_bits_buf(pstr_it_bit_buff, 0, 1); + bp++; + } + } + + if (quant[2 * i + 1] != 0) { + if (quant[2 * i + 1] > 0) { + iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); + bp++; + } else { + iusace_write_bits_buf(pstr_it_bit_buff, 0, 1); + bp++; + } + } + } + + for (i = 0; i < nt; i++) { + ptr_c_prev[i] = ptr_c_pres[i]; + ptr_c_pres[i] = 1; + } + } + + return bp; +} + +WORD32 iusace_arith_enc_spec(ia_bit_buf_struct *it_bit_buf, WORD32 window_sequence, + WORD32 *ptr_x_ac_enc, WORD32 max_spec_coefficients, + WORD32 *ptr_c_pres, WORD32 *ptr_c_prev, WORD32 *ptr_size_prev, + WORD32 arith_reset_flag, WORD32 ccfl) { + LOOPIDX i; + WORD32 write_flag = (it_bit_buf != NULL); + WORD32 size; + WORD32 num_wins = (window_sequence == EIGHT_SHORT_SEQUENCE) ? MAX_SHORT_WINDOWS : 1; + WORD32 bits_data_written = 0; + + switch (window_sequence) { + case ONLY_LONG_SEQUENCE: + case LONG_START_SEQUENCE: + case STOP_START_SEQUENCE: + case LONG_STOP_SEQUENCE: + size = ccfl; + break; + case EIGHT_SHORT_SEQUENCE: + size = ccfl >> 3; + break; + default: + size = ccfl >> 3; + break; + } + + iusace_arith_map_context(size, *ptr_size_prev, ptr_c_pres, ptr_c_prev, arith_reset_flag); + + if (max_spec_coefficients > 0) { + for (i = 0; i < num_wins; i++) { + bits_data_written = iusace_arith_encode_level2( + it_bit_buf, bits_data_written, ptr_c_pres + 2, ptr_c_prev + 2, &ptr_x_ac_enc[i * size], + max_spec_coefficients / 2, size / 2, 2); + } + } + + if (write_flag) { + *ptr_size_prev = size; + } + + return bits_data_written; +} + +WORD32 iusace_tcx_coding(ia_bit_buf_struct *pstr_it_bit_buff, WORD32 tcx_size, + WORD32 max_tcx_size, WORD32 *ptr_quant, WORD32 *c_pres, WORD32 *c_prev) { + WORD32 bits_written = 0; + + iusace_arith_map_context(tcx_size, max_tcx_size, c_pres, c_prev, 0); + + bits_written = + iusace_arith_encode_level2(pstr_it_bit_buff, bits_written, c_pres + 2, c_prev + 2, + &ptr_quant[0], tcx_size / 2, tcx_size / 2, 2); + + iusace_arith_map_context(max_tcx_size, tcx_size, c_pres, c_prev, 0); + + return bits_written; +} + +WORD32 iusace_arith_done(ia_bit_buf_struct *pstr_it_bit_buff, WORD32 bp, iusace_state_arith *s) { + WORD32 low, high; + WORD32 bits_to_follow; + + low = s->low; + high = s->high; + bits_to_follow = s->value + 1; + + if (low < 16384) { + iusace_write_bits_buf(pstr_it_bit_buff, 0, 1); + bp++; + while (bits_to_follow) { + iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); + bp++; + bits_to_follow--; + } + } else { + iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); + bp++; + while (bits_to_follow) { + iusace_write_bits_buf(pstr_it_bit_buff, 0, 1); + bp++; + bits_to_follow--; + } + } + + s->low = low; + s->high = high; + s->value = bits_to_follow; + + return bp; +} + +WORD32 iusace_arith_encode(ia_bit_buf_struct *pstr_it_bit_buff, WORD32 bp, iusace_state_arith *s, + WORD32 symbol, UWORD16 const *cum_freq) { + WORD32 low, high, range; + WORD32 bits_to_follow; + + high = s->high; + low = s->low; + range = high - low + 1; + + if (symbol > 0) { + high = low + ((range * cum_freq[symbol - 1]) >> 14) - 1; + } + + low = low + ((range * cum_freq[symbol]) >> 14); + + bits_to_follow = s->value; + + for (;;) { + if (high < 32768) { + iusace_write_bits_buf(pstr_it_bit_buff, 0, 1); + bp++; + while (bits_to_follow) { + iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); + bp++; + bits_to_follow--; + } + } else if (low >= 32768) { + iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); + bp++; + while (bits_to_follow) { + iusace_write_bits_buf(pstr_it_bit_buff, 0, 1); + bp++; + bits_to_follow--; + } + low -= 32768; + high -= 32768; + } else if (low >= 16384 && high < 49152) { + bits_to_follow += 1; + low -= 16384; + high -= 16384; + } else + break; + + low += low; + high += high + 1; + } + + s->low = low; + s->high = high; + s->value = bits_to_follow; + + return bp; +} diff --git a/encoder/iusace_arith_enc.h b/encoder/iusace_arith_enc.h new file mode 100644 index 0000000..ada2240 --- /dev/null +++ b/encoder/iusace_arith_enc.h @@ -0,0 +1,47 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +#ifndef MIN +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif + +#ifndef MAX +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif + +typedef struct { + WORD32 low; + WORD32 high; + WORD32 value; +} iusace_state_arith; + +WORD32 iusace_arith_enc_spec(ia_bit_buf_struct *it_bit_buf, WORD32 window_sequence, + WORD32 *ptr_x_ac_enc, WORD32 max_spec_coefficients, + WORD32 *ptr_c_pres, WORD32 *ptr_c_prev, WORD32 *ptr_size_prev, + WORD32 arith_reset_flag, WORD32 ccfl); + +WORD32 iusace_tcx_coding(ia_bit_buf_struct *pstr_it_bit_buff, WORD32 tcx_size, + WORD32 max_tcx_size, WORD32 *ptr_quant, WORD32 *c_pres, WORD32 *c_prev); + +WORD32 iusace_arith_done(ia_bit_buf_struct *pstr_it_bit_buff, WORD32 bp, iusace_state_arith *s); + +WORD32 iusace_arith_encode(ia_bit_buf_struct *pstr_it_bit_buff, WORD32 bp, iusace_state_arith *s, + WORD32 symbol, UWORD16 const *cum_freq); diff --git a/encoder/iusace_avq_enc.c b/encoder/iusace_avq_enc.c new file mode 100644 index 0000000..3a53c2c --- /dev/null +++ b/encoder/iusace_avq_enc.c @@ -0,0 +1,343 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include +#include "ixheaac_type_def.h" +#include "iusace_avq_enc.h" + +static VOID iusace_gosset_compute_rank_and_sign(WORD32 *x, WORD32 *rank, WORD32 *sign_code) { + WORD32 xs[8], a[8], q, d[8], w[8], A, B, idx, tmp, abs_i, abs_j; + WORD32 i, j, k; + for (i = 0; i < 8; i++) { + xs[i] = x[i]; + } + for (k = 0; k < 7; k++) { + j = k; + for (i = k + 1; i < 8; i++) { + abs_j = abs(xs[j]); + abs_i = abs(xs[i]); + if (abs_i >= abs_j) { + if (abs_i > xs[j]) { + j = i; + } + } + } + if (j > k) { + tmp = xs[k]; + xs[k] = xs[j]; + xs[j] = tmp; + } + } + *sign_code = 0; + for (i = 0; i < 8; i++) { + if (xs[i] < 0) { + *sign_code += iusace_pow2_table[i]; + } + } + a[0] = xs[0]; + q = 1; + for (i = 1; i < 8; i++) { + if (xs[i] != xs[i - 1]) { + a[q] = xs[i]; + q++; + } + } + for (i = 0; i < 8; i++) { + for (j = 0; j < q; j++) { + if (x[i] == a[j]) { + d[i] = j; + break; + } + } + } + *rank = 0; + for (j = 0; j < q; j++) { + w[j] = 0; + } + B = 1; + for (i = 7; i >= 0; i--) { + idx = d[i]; + w[idx]++; + B *= w[idx]; + A = 0; + for (j = 0; j < idx; j++) { + A += w[j]; + } + if (A > 0) { + *rank += A * iusace_factorial_table[i] / B; + } + } +} + +static VOID iusace_gosset_compute_base_idx(WORD32 *x, WORD32 ka, WORD32 *idx) { + WORD32 rank, offset, code, i, ks; + iusace_gosset_compute_rank_and_sign(x, &rank, &code); + ks = -1; + for (i = iusace_iso_code_index_table[ka]; i < LEN_SIGN_LEADER; i++) { + if (code == iusace_iso_code_data_table[i]) { + ks = i; + break; + } + } + if (ks == -1) { + ks = 0; + } + offset = iusace_signed_leader_is[ks]; + *idx = offset + rank; + return; +} + +static WORD32 iusace_find_absolute_leader(WORD32 *y) { + WORD32 i, s, C[8], nb, pos, ka; + long id; + for (i = 0; i < 8; i++) { + C[i] = y[i] * y[i]; + } + s = 0; + for (i = 0; i < 8; i++) { + s += C[i]; + } + s >>= 3; + ka = LEN_ABS_LEADER + 1; + if (s == 0) { + ka = LEN_ABS_LEADER; + } else { + if (s <= NB_SPHERE) { + id = 0; + for (i = 0; i < 8; i++) { + id += C[i] * C[i]; + } + id = id >> 3; + nb = iusace_da_num_bits[s - 1]; + pos = iusace_da_pos[s - 1]; + for (i = 0; i < nb; i++) { + if (id == (long)iusace_da_id[pos]) { + ka = pos; + break; + } + pos++; + } + } + } + return (ka); +} + +static VOID iusace_nearest_neighbor_2d(FLOAT32 *x, WORD32 *y) { + WORD32 i, j; + WORD64 sum; + FLOAT32 diff[8], em; + sum = 0; + for (i = 0; i < 8; i++) { + if (x[i] < 0) { + y[i] = -2 * (((WORD32)(1.0 - x[i])) >> 1); + } else { + y[i] = 2 * (((WORD32)(1.0 + x[i])) >> 1); + } + sum += y[i]; + } + if (sum % 4) { + FLOAT32 s; + em = 0; + j = 0; + for (i = 0; i < 8; i++) { + diff[i] = x[i] - y[i]; + s = (FLOAT32)fabs(diff[i]); + if (em < s) { + em = s; + j = i; + } + } + if (diff[j] < 0) { + y[j] -= 2; + } else { + y[j] += 2; + } + } + return; +} + +VOID iusace_find_nearest_neighbor(FLOAT32 *bk, WORD32 *ck) { + WORD32 i, y1[8], y2[8]; + FLOAT32 e1k, e2k, x1[8], tmp; + + iusace_nearest_neighbor_2d(bk, y1); + + for (i = 0; i < 8; i++) { + x1[i] = bk[i] - 1.0f; + } + iusace_nearest_neighbor_2d(x1, y2); + for (i = 0; i < 8; i++) { + y2[i] += 1; + } + /* Compute e1k = (Bk - y1k)^2 and e2k = (Bk – y2k)^2 */ + e1k = e2k = 0.0; + for (i = 0; i < 8; i++) { + tmp = bk[i] - y1[i]; + e1k += tmp * tmp; + tmp = bk[i] - y2[i]; + e2k += tmp * tmp; + } + + /* Select best lattice point */ + if (e1k < e2k) { + for (i = 0; i < 8; i++) { + ck[i] = y1[i]; + } + } else { + for (i = 0; i < 8; i++) { + ck[i] = y2[i]; + } + } + return; +} + +static VOID iusace_vononoi_idx(WORD32 *kv, WORD32 m, WORD32 *y) { + WORD32 i, v[8], tmp, sum, *ptr1, *ptr2; + FLOAT32 z[8]; + for (i = 0; i < 8; i++) { + y[i] = kv[7]; + } + z[7] = (FLOAT32)y[7] / m; + sum = 0; + for (i = 6; i >= 1; i--) { + tmp = kv[i] << 1; + sum += tmp; + y[i] += tmp; + z[i] = (FLOAT32)y[i] / m; + } + y[0] += (4 * kv[0] + sum); + z[0] = (FLOAT32)(y[0] - 2) / m; + iusace_find_nearest_neighbor(z, v); + ptr1 = y; + ptr2 = v; + for (i = 0; i < 8; i++) { + *ptr1++ -= m * *ptr2++; + } +} + +static VOID iusace_compute_coord(WORD32 *y, WORD32 *k) { + WORD32 i, tmp, sum; + k[7] = y[7]; + tmp = y[7]; + sum = 5 * y[7]; + for (i = 6; i >= 1; i--) { + k[i] = (y[i] - tmp) >> 1; + sum -= y[i]; + } + k[0] = (y[0] + sum) >> 2; +} + +VOID iusace_apply_voronoi_ext(WORD32 *x, WORD32 *n, WORD32 *idx, WORD32 *k) { + WORD32 ka, c[8]; + WORD32 i, r, m, v[8], c_tmp[8], k_mod[8], k_tmp[8], iter, ka_tmp, n_tmp, mask; + FLOAT32 sphere; + ka = iusace_find_absolute_leader(x); + *n = iusace_da_nq[ka]; + if (*n <= 4) { + for (i = 0; i < 8; i++) { + c[i] = x[i]; + } + } else { + sphere = 0.0; + for (i = 0; i < 8; i++) { + sphere += (FLOAT32)x[i] * (FLOAT32)x[i]; + } + sphere *= 0.125; + r = 1; + sphere *= 0.25; + while (sphere > 11.0) { + r++; + sphere *= 0.25; + } + iusace_compute_coord(x, k_mod); + m = 1 << r; + mask = m - 1; + for (iter = 0; iter < 2; iter++) { + for (i = 0; i < 8; i++) { + k_tmp[i] = k_mod[i] & mask; + } + iusace_vononoi_idx(k_tmp, m, v); + for (i = 0; i < 8; i++) { + c_tmp[i] = (x[i] - v[i]) / m; + } + ka_tmp = iusace_find_absolute_leader(c_tmp); + n_tmp = iusace_da_nq[ka_tmp]; + if (n_tmp > 4) { + r++; + m = m << 1; + mask = ((mask << 1) + 1); + } else { + if (n_tmp < 3) { + n_tmp = 3; + } + ka = ka_tmp; + *n = n_tmp + 2 * r; + for (i = 0; i < 8; i++) { + k[i] = k_tmp[i]; + } + for (i = 0; i < 8; i++) { + c[i] = c_tmp[i]; + } + r--; + m = m >> 1; + mask = mask >> 1; + } + } + } + + if (*n > 0) { + iusace_gosset_compute_base_idx(c, ka, idx); + } + return; +} + +VOID iusace_alg_vec_quant(FLOAT32 *ptr_input, WORD32 *ptr_out, WORD32 *ptr_lpc_idx) { + WORD32 i, l, nq, pos, c[8], kv[8]; + FLOAT32 x1[8]; + WORD32 lpc_index; + + pos = 2; + for (l = 0; l < 2; l++) { + for (i = 0; i < 8; i++) { + x1[i] = ptr_input[l * 8 + i]; + kv[i] = 0; + } + + iusace_find_nearest_neighbor(x1, c); + + iusace_apply_voronoi_ext(c, &nq, &lpc_index, kv); + + for (i = 0; i < 8; i++) { + ptr_out[l * 8 + i] = c[i]; + } + + ptr_lpc_idx[l] = nq; + + if (nq > 0) { + ptr_lpc_idx[pos++] = lpc_index; + for (i = 0; i < 8; i++) { + ptr_lpc_idx[pos++] = kv[i]; + } + } + } + + return; +} diff --git a/encoder/iusace_avq_enc.h b/encoder/iusace_avq_enc.h new file mode 100644 index 0000000..d38186e --- /dev/null +++ b/encoder/iusace_avq_enc.h @@ -0,0 +1,38 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +#define NB_SPHERE 32 +#define LEN_ABS_LEADER 37 +#define LEN_SIGN_LEADER 226 + +VOID iusace_find_nearest_neighbor(FLOAT32 *bk, WORD32 *ck); +VOID iusace_apply_voronoi_ext(WORD32 *x, WORD32 *n, WORD32 *idx, WORD32 *k); +VOID iusace_alg_vec_quant(FLOAT32 *ptr_input, WORD32 *ptr_out, WORD32 *ptr_lpc_idx); + +extern const WORD32 iusace_pow2_table[8]; +extern const WORD32 iusace_factorial_table[8]; +extern const WORD32 iusace_iso_code_index_table[LEN_ABS_LEADER]; +extern const UWORD8 iusace_iso_code_data_table[LEN_SIGN_LEADER]; +extern const UWORD32 iusace_signed_leader_is[LEN_SIGN_LEADER]; +extern const WORD32 iusace_da_nq[], iusace_da_pos[], iusace_da_num_bits[]; +extern const UWORD32 iusace_da_id[]; +extern const FLOAT32 iusace_wlsf_factor_table[4]; +extern const FLOAT32 iusace_dico_lsf_abs_8b_flt[16 * 256]; diff --git a/encoder/iusace_avq_rom.c b/encoder/iusace_avq_rom.c new file mode 100644 index 0000000..d919344 --- /dev/null +++ b/encoder/iusace_avq_rom.c @@ -0,0 +1,674 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include "ixheaac_type_def.h" + +#define NB_SPHERE 32 +#define LEN_ABS_LEADER 37 +#define LEN_SIGN_LEADER 226 + +const WORD32 iusace_pow2_table[8] = {128, 64, 32, 16, 8, 4, 2, 1}; + +const WORD32 iusace_factorial_table[8] = {5040, 720, 120, 24, 6, 2, 1, 1}; + +const WORD32 iusace_da_pos[NB_SPHERE] = {0, 2, 5, 8, 13, 18, 20, 22, 23, 25, 26, + 27, 27, 28, 28, 28, 29, 30, 31, 31, 32, 32, + 32, 32, 32, 34, 35, 35, 35, 35, 35, 35}; + +const WORD32 iusace_da_num_bits[NB_SPHERE] = {2, 3, 3, 5, 5, 2, 2, 1, 2, 1, 1, 0, 1, 0, 0, 1, + 1, 1, 0, 1, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 1}; + +const WORD32 iusace_da_nq[LEN_ABS_LEADER + 2] = {2, 2, 3, 3, 2, 4, 4, 3, 4, 4, 4, 3, 4, + 4, 4, 4, 4, 3, 4, 4, 4, 4, 3, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 100}; + +const UWORD32 iusace_da_id[LEN_ABS_LEADER] = { + 0x0001, 0x0004, 0x0008, 0x000B, 0x0020, 0x000C, 0x0015, 0x0024, 0x0010, 0x001F, + 0x0028, 0x0040, 0x004F, 0x0029, 0x002C, 0x0044, 0x0059, 0x00A4, 0x0060, 0x00A8, + 0x00C4, 0x012D, 0x0200, 0x0144, 0x0204, 0x0220, 0x0335, 0x04E4, 0x0400, 0x0584, + 0x0A20, 0x0A40, 0x09C4, 0x12C4, 0x0C20, 0x2000, 0x4E20}; + +const UWORD8 iusace_iso_code_data_table[LEN_SIGN_LEADER] = { + 0, 3, 15, 63, 255, 0, 64, 192, 0, 16, 48, 112, 240, 1, 7, 31, 127, 128, 131, + 143, 191, 0, 128, 0, 4, 12, 28, 60, 124, 252, 0, 3, 15, 63, 65, 71, 95, 192, + 195, 207, 255, 0, 32, 96, 128, 160, 224, 0, 1, 3, 7, 15, 31, 63, 127, 255, 1, + 7, 31, 32, 35, 47, 97, 103, 127, 224, 227, 239, 0, 8, 24, 56, 120, 128, 136, 152, + 184, 248, 0, 64, 192, 0, 3, 15, 63, 129, 135, 159, 255, 0, 3, 15, 17, 23, 48, + 51, 63, 113, 119, 240, 243, 255, 0, 2, 6, 14, 30, 62, 126, 128, 130, 134, 142, 158, + 190, 254, 0, 16, 48, 64, 80, 112, 192, 208, 240, 1, 7, 31, 64, 67, 79, 127, 128, + 131, 143, 191, 193, 199, 223, 0, 64, 128, 192, 0, 32, 96, 224, 0, 16, 48, 112, 128, + 144, 176, 240, 0, 32, 64, 96, 128, 160, 192, 224, 1, 7, 31, 127, 128, 131, 143, 191, + 0, 128, 0, 64, 192, 0, 32, 96, 128, 160, 224, 0, 64, 128, 192, 0, 3, 15, 63, + 129, 135, 159, 255, 0, 64, 128, 192, 0, 64, 192, 0, 64, 128, 192, 0, 128, 0, 64, + 128, 192, 0, 64, 192, 0, 64, 128, 192, 0, 64, 128, 192, 0, 128, 0, 128}; + +const WORD32 iusace_iso_code_index_table[LEN_ABS_LEADER] = { + 0, 5, 8, 13, 21, 23, 30, 41, 47, 56, 68, 78, 81, 89, 102, 116, 125, 139, 143, + 147, 155, 163, 171, 173, 176, 182, 186, 194, 198, 201, 205, 207, 211, 214, 218, 222, 224}; + +const UWORD32 iusace_signed_leader_is[LEN_SIGN_LEADER] = { + 0, 1, 29, 99, 127, 128, 156, 212, 256, 326, 606, 1026, 1306, + 1376, 1432, 1712, 1880, 1888, 1896, 2064, 2344, 240, 248, 0, 28, 196, + 616, 1176, 1596, 1764, 1792, 1820, 2240, 2660, 2688, 3024, 4144, 4480, 4508, + 4928, 5348, 2400, 2568, 2904, 3072, 3240, 3576, 5376, 5377, 5385, 5413, 5469, + 5539, 5595, 5623, 5631, 5632, 5912, 6472, 6528, 6696, 8376, 9216, 10056, 11736, + 11904, 11960, 12520, 12800, 13080, 14200, 15880, 17000, 17280, 17560, 18680, 20360, 21480, + 3744, 3772, 3828, 21760, 21768, 21936, 22216, 22272, 22328, 22608, 22776, 22784, 22854, + 23274, 23344, 24464, 25584, 26004, 28524, 28944, 30064, 31184, 31254, 31674, 31744, 31800, + 32136, 32976, 34096, 34936, 35272, 35328, 35384, 35720, 36560, 37680, 38520, 38856, 38912, + 39332, 40172, 40592, 41432, 43112, 43952, 44372, 45212, 45632, 45968, 47088, 47424, 47480, + 48320, 49160, 49216, 49272, 50112, 50952, 51008, 51344, 52464, 3856, 3912, 3968, 4024, + 52800, 52856, 53024, 53192, 53248, 53528, 54368, 55208, 55488, 55768, 56608, 57448, 57728, + 58064, 58400, 58736, 59072, 59408, 59744, 60080, 60416, 60472, 60752, 60920, 60928, 60936, + 61104, 61384, 4080, 4088, 61440, 61468, 61524, 61552, 61720, 62056, 62224, 62392, 62728, + 62896, 62952, 63008, 63064, 63120, 63128, 63296, 63576, 63632, 63688, 63968, 64136, 64144, + 64200, 64256, 64312, 64368, 64396, 64452, 64480, 64536, 64592, 64648, 64704, 64712, 64720, + 64776, 64832, 64888, 64944, 64972, 65028, 65056, 65112, 65168, 65224, 65280, 65336, 65392, + 65448, 65504, 65512, 65520, 65528}; + +const FLOAT32 iusace_dico_lsf_abs_8b_flt[16 * 256] = { + 377.3749f, 688.0079f, 1147.3799f, 1461.0438f, 1786.7794f, 2143.6711f, 2522.1946f, + 2889.7402f, 3263.6023f, 3628.4624f, 4005.4351f, 4379.4170f, 4783.9556f, 5157.1753f, + 5555.1797f, 5926.6816f, 601.5123f, 1066.8242f, 1384.3585f, 1652.9448f, 1978.3910f, + 2311.2676f, 2674.0537f, 3010.3896f, 3360.0623f, 3725.9336f, 4093.3335f, 4470.6431f, + 4859.1006f, 5210.4717f, 5598.3716f, 5954.4204f, 552.5036f, 859.7047f, 1355.2023f, + 1624.9041f, 1887.5609f, 2173.1638f, 2540.7429f, 2926.8169f, 3323.2173f, 3680.7197f, + 4008.3447f, 4330.8442f, 4692.8228f, 5033.9697f, 5443.3467f, 5875.4497f, 459.4534f, + 793.3189f, 1293.7278f, 1617.3970f, 1920.0642f, 2192.2153f, 2487.5627f, 2772.1514f, + 3111.3823f, 3461.2671f, 3867.0176f, 4279.8550f, 4741.0664f, 5141.0181f, 5552.8237f, + 5933.6934f, 327.9834f, 430.4954f, 723.9031f, 1528.6172f, 1763.1125f, 2013.7936f, + 2334.2153f, 2569.0334f, 3017.9436f, 3308.0610f, 3591.7820f, 3865.5430f, 4693.5786f, + 5286.7646f, 5647.7036f, 5987.2305f, 455.0753f, 606.0817f, 963.7564f, 1374.9937f, + 1536.4897f, 1914.7618f, 2376.9631f, 2580.8184f, 2989.1501f, 3258.8386f, 3485.1460f, + 3741.1270f, 4297.4912f, 5207.3779f, 5672.3818f, 5980.5322f, 434.9507f, 558.8508f, + 890.7061f, 1355.7625f, 1552.6155f, 1895.7960f, 2222.5579f, 2502.6079f, 2841.8738f, + 3137.5264f, 3367.7336f, 3860.7769f, 4795.2554f, 5090.9370f, 5421.8218f, 5874.4287f, + 281.0164f, 404.5417f, 729.2898f, 997.1851f, 1699.8862f, 1961.3673f, 2255.7202f, + 2540.9187f, 2804.4553f, 3057.1843f, 3750.2288f, 4340.9893f, 4716.8647f, 5002.7471f, + 5477.2998f, 5965.7402f, 372.2410f, 505.3570f, 762.3755f, 997.3586f, 1174.4255f, + 1986.1741f, 2368.1367f, 2624.1733f, 3194.6084f, 3403.2793f, 3877.7622f, 4425.7676f, + 4824.7837f, 5158.1606f, 5532.7466f, 5893.5483f, 367.3766f, 501.1806f, 824.5358f, + 1090.6857f, 1271.9792f, 1527.7137f, 2381.4382f, 2694.4634f, 2964.5359f, 3639.4832f, + 3946.4038f, 4254.3916f, 4645.8076f, 5033.5396f, 5373.8735f, 5878.4385f, 229.4505f, + 352.5671f, 701.0831f, 1226.4518f, 1678.3601f, 1895.7949f, 2140.0664f, 2526.5515f, + 3080.3391f, 3297.8284f, 3845.3987f, 4427.9785f, 4704.4551f, 4997.4155f, 5434.0698f, + 5918.4785f, 336.3082f, 516.7915f, 881.9847f, 1272.5824f, 1505.1870f, 1880.7520f, + 2274.9458f, 2611.0083f, 3126.5256f, 3655.5332f, 4183.3877f, 4668.2993f, 5004.0029f, + 5305.3491f, 5650.4985f, 5943.7383f, 296.0867f, 469.6519f, 956.5997f, 1224.1262f, + 1443.0049f, 1727.6880f, 2216.1677f, 2689.3677f, 3060.4456f, 3520.9438f, 3916.6050f, + 4343.7954f, 4763.8906f, 5156.0132f, 5553.8115f, 5936.9634f, 407.1503f, 577.5120f, + 839.7361f, 1455.3907f, 1665.2137f, 1935.0054f, 2398.0537f, 2652.2605f, 3111.1831f, + 3505.5962f, 3766.7554f, 4204.8730f, 4699.1631f, 4970.8652f, 5295.5962f, 5695.6919f, + 281.0083f, 361.8386f, 950.9102f, 1464.1158f, 1634.7019f, 1965.4950f, 2211.1406f, + 2662.1055f, 2846.0122f, 3585.8884f, 4048.7148f, 4358.9150f, 4683.8755f, 5046.0908f, + 5400.0859f, 5956.1040f, 279.1811f, 393.9142f, 876.8306f, 1502.2417f, 1673.0590f, + 2288.7161f, 2545.3674f, 3028.9507f, 3517.5840f, 3824.4246f, 4144.8486f, 4481.8140f, + 4821.2769f, 5162.3975f, 5542.8560f, 5928.5854f, 379.7892f, 500.9199f, 725.0223f, + 998.7143f, 1179.6127f, 1771.9886f, 2775.4812f, 3136.8457f, 3378.6143f, 3674.0188f, + 3946.3604f, 4184.4824f, 4521.5454f, 4934.8940f, 5315.5029f, 5759.7544f, 317.4339f, + 442.2628f, 778.7388f, 1167.8633f, 1356.1576f, 1578.5603f, 1840.1584f, 2870.7527f, + 3236.1504f, 3502.7249f, 3876.3696f, 4100.5244f, 4650.2632f, 5235.1890f, 5665.2285f, + 5999.0649f, 350.2696f, 492.2163f, 763.0640f, 1264.7550f, 1515.0244f, 1755.7783f, + 2489.3274f, 2898.6252f, 3143.1018f, 3643.0640f, 4035.0657f, 4255.0889f, 4641.7231f, + 5138.5107f, 5557.1318f, 5920.2402f, 301.3833f, 464.9852f, 762.3419f, 1012.2126f, + 1803.5172f, 2192.4214f, 2651.6287f, 3013.6697f, 3251.3591f, 3539.4675f, 3946.3433f, + 4469.3560f, 4890.7446f, 5200.4878f, 5509.6753f, 5910.2397f, 253.1752f, 356.8990f, + 630.3325f, 1163.1683f, 1528.6230f, 2023.4438f, 2488.6001f, 2745.5627f, 2933.7024f, + 3237.4414f, 3976.9258f, 4415.2534f, 4789.9131f, 5194.3423f, 5714.6445f, 6032.4160f, + 265.1815f, 364.7549f, 590.0148f, 805.2595f, 1564.7582f, 2150.6536f, 2365.6501f, + 2598.7876f, 2861.5334f, 3514.1265f, 4005.6328f, 4609.3091f, 4955.4478f, 5238.4116f, + 5519.5884f, 5890.7925f, 209.3544f, 313.1497f, 503.2642f, 949.4504f, 1729.7280f, + 1912.6814f, 2117.5051f, 2498.6272f, 3284.6587f, 3810.8555f, 4105.0195f, 4349.5151f, + 4770.3682f, 5210.2910f, 5585.1533f, 5970.3638f, 302.3150f, 415.6502f, 684.1018f, + 922.3598f, 1489.4418f, 2235.6252f, 2449.9773f, 2800.6938f, 3061.3721f, 3526.1001f, + 3905.8174f, 4170.7891f, 4446.4209f, 4907.9937f, 5470.7158f, 5914.7261f, 264.9068f, + 366.4342f, 582.8182f, 790.8568f, 1619.4548f, 2034.0782f, 2337.6724f, 2632.1714f, + 2933.2356f, 3430.1858f, 3815.0198f, 4276.3931f, 4748.3149f, 5164.0098f, 5553.3320f, + 5974.9092f, 249.6359f, 361.9234f, 581.9844f, 841.1097f, 1657.5543f, 2184.4114f, + 2525.9739f, 2820.0503f, 3120.7190f, 3623.7678f, 4050.5435f, 4434.5742f, 4802.6782f, + 5171.8438f, 5575.0068f, 5963.7402f, 290.1085f, 404.2538f, 664.1223f, 878.2748f, + 1237.1085f, 2237.4707f, 2497.5647f, 2957.7786f, 3289.3928f, 3626.5276f, 4190.9243f, + 4594.6450f, 4981.7456f, 5283.5513f, 5617.1538f, 5938.3760f, 182.7846f, 270.3831f, + 490.2131f, 1070.2524f, 1674.5724f, 2092.4905f, 2524.1472f, 2929.3523f, 3334.8005f, + 3712.0061f, 4101.2896f, 4475.7324f, 4866.1919f, 5231.7559f, 5606.4077f, 5960.9644f, + 286.7701f, 386.1487f, 577.4210f, 764.3087f, 1151.2404f, 2014.4502f, 2399.8547f, + 2879.0371f, 3160.2502f, 3450.6274f, 3869.8240f, 4368.3618f, 4816.7861f, 5187.6450f, + 5564.7231f, 5962.0386f, 179.9538f, 266.0682f, 647.9122f, 1380.2810f, 1776.1240f, + 2208.4592f, 2590.6843f, 2993.6758f, 3368.2034f, 3753.2156f, 4125.2124f, 4508.6050f, + 4878.9932f, 5249.3291f, 5612.5049f, 5965.2134f, 309.2416f, 434.7111f, 724.6614f, + 936.5360f, 1264.9886f, 2272.1338f, 2548.4519f, 2904.0798f, 3313.4990f, 3579.7854f, + 3914.5811f, 4297.5938f, 4756.9072f, 5163.2017f, 5592.2822f, 5943.7222f, 256.9009f, + 393.7155f, 769.3966f, 1200.9640f, 1774.4797f, 2307.9629f, 2794.6799f, 3165.9431f, + 3507.7952f, 3840.5791f, 4142.8877f, 4453.5078f, 4790.6973f, 5142.6123f, 5530.5977f, + 5923.2188f, 394.1425f, 602.0079f, 934.5173f, 1352.9718f, 1813.9639f, 2172.5435f, + 2603.7295f, 2963.9590f, 3335.2344f, 3732.0515f, 4120.0151f, 4487.9668f, 4877.6294f, + 5238.9336f, 5596.1479f, 5939.6489f, 373.0307f, 665.4328f, 1227.4684f, 1524.6017f, + 1947.3784f, 2361.6384f, 2778.1921f, 3134.5396f, 3462.3992f, 3752.4592f, 4069.0352f, + 4404.2720f, 4782.2241f, 5145.0581f, 5541.9980f, 5932.9136f, 449.9942f, 814.1862f, + 1344.2784f, 1682.7061f, 2086.3599f, 2486.9709f, 2916.1177f, 3265.9099f, 3616.3977f, + 3919.6345f, 4218.5342f, 4519.2207f, 4857.5220f, 5193.5269f, 5573.7339f, 5934.5400f, + 531.4455f, 965.7403f, 1458.5353f, 1773.3784f, 2236.0146f, 2650.9109f, 3099.2871f, + 3467.1567f, 3809.7056f, 4094.6472f, 4378.5811f, 4660.2471f, 4962.5078f, 5270.9863f, + 5629.4160f, 5973.6450f, 565.5986f, 1091.1300f, 1561.4944f, 1983.5482f, 2492.8821f, + 2897.5085f, 3233.5361f, 3539.8831f, 3838.6494f, 4093.4460f, 4372.1924f, 4678.2251f, + 4999.2646f, 5325.0371f, 5672.8887f, 5998.9990f, 581.0623f, 976.0275f, 1447.0302f, + 1779.9243f, 2148.2158f, 2543.8347f, 2979.5061f, 3373.6099f, 3796.8259f, 4164.8242f, + 4510.5493f, 4853.5527f, 5175.6318f, 5465.3647f, 5763.2334f, 6050.6582f, 429.4613f, + 802.5781f, 1229.0529f, 1512.6678f, 1835.8625f, 2216.9915f, 2625.3999f, 2995.9927f, + 3379.5146f, 3764.7837f, 4156.1382f, 4532.4570f, 4906.4678f, 5262.8960f, 5626.6519f, + 5970.6504f, 224.5468f, 328.6938f, 615.8844f, 1207.4470f, 1520.9565f, 1865.9806f, + 2182.4731f, 2431.4897f, 3239.3486f, 3490.9065f, 3775.7139f, 4291.4312f, 4740.0815f, + 5192.0786f, 5532.9302f, 5928.7236f, 312.1133f, 424.3103f, 716.4448f, 921.9969f, + 1244.5491f, 2017.9143f, 2248.4170f, 2840.0688f, 3138.9390f, 3399.7288f, 3723.3479f, + 3999.6824f, 4582.2339f, 5148.5166f, 5631.8989f, 6000.7192f, 373.5378f, 506.7356f, + 789.6149f, 942.6201f, 1695.8035f, 2021.6426f, 2323.3867f, 2649.5979f, 2853.1729f, + 3169.5815f, 3524.9375f, 3848.6399f, 4261.7319f, 4978.9668f, 5505.4004f, 5924.7939f, + 503.2296f, 724.8124f, 940.3833f, 1220.5646f, 1439.8641f, 1726.9827f, 2215.5464f, + 2476.0925f, 2846.8127f, 3232.0950f, 3638.5989f, 3986.3333f, 4371.3052f, 5022.0664f, + 5657.4897f, 6040.3452f, 398.3355f, 530.8898f, 835.5377f, 1058.3699f, 1327.2036f, + 1814.9178f, 2114.2439f, 2515.8892f, 2754.9077f, 3094.8794f, 3598.7061f, 3981.2385f, + 4605.9160f, 5110.8364f, 5550.1899f, 5953.9600f, 327.7583f, 454.8903f, 825.9029f, + 1025.4349f, 1321.1567f, 1551.4836f, 1978.2037f, 2838.9021f, 3111.9041f, 3417.3940f, + 3841.0564f, 4696.0547f, 5126.1641f, 5409.5347f, 5711.7163f, 5968.3394f, 327.1260f, + 431.3983f, 721.9533f, 871.1266f, 1507.7616f, 1847.8716f, 2144.9641f, 2491.1108f, + 2702.0847f, 3483.1516f, 3917.5173f, 4254.1260f, 4704.4863f, 4981.6284f, 5450.1035f, + 5937.7861f, 443.5867f, 610.7686f, 818.9614f, 999.3525f, 1181.9182f, 1884.4948f, + 2243.3950f, 2522.8867f, 2993.8594f, 3196.6631f, 3835.5020f, 4233.2568f, 4506.8604f, + 4985.0249f, 5544.1382f, 5980.0083f, 395.7788f, 582.9504f, 822.1151f, 1013.0453f, + 1224.6812f, 1988.4263f, 2452.4744f, 2686.4263f, 2952.8831f, 3135.0867f, 3562.5471f, + 4006.6929f, 4401.7471f, 5038.5654f, 5567.4189f, 5986.0850f, 264.3071f, 372.0398f, + 616.4940f, 842.1705f, 1350.0250f, 1822.1957f, 2165.8896f, 2662.2937f, 3055.4390f, + 3502.6787f, 3923.4236f, 4352.6587f, 4772.5068f, 5158.1309f, 5573.9385f, 5972.6895f, + 218.7390f, 325.2024f, 635.0441f, 1103.4701f, 1636.4287f, 2070.2615f, 2274.2910f, + 2453.2002f, 3069.4382f, 3615.7065f, 3980.0811f, 4484.8662f, 4848.6416f, 5093.7163f, + 5522.6973f, 5907.4048f, 260.0797f, 461.2137f, 1049.2261f, 1334.1865f, 1628.6233f, + 2014.9823f, 2413.4802f, 2844.4973f, 3232.3040f, 3661.0122f, 4069.8274f, 4466.5210f, + 4857.6553f, 5234.4463f, 5608.4517f, 5954.7920f, 301.7969f, 406.3861f, 706.7324f, + 1387.1207f, 1581.4719f, 2004.7585f, 2291.9421f, 2548.9978f, 3076.8755f, 3343.1306f, + 3623.1770f, 4279.7432f, 4777.6563f, 5084.3960f, 5473.4536f, 5872.0615f, 344.0269f, + 472.3550f, 776.6819f, 1455.1270f, 1611.6870f, 2012.4386f, 2417.4033f, 2621.8564f, + 3318.9663f, 3709.0132f, 3944.1958f, 4299.0293f, 4776.4038f, 5184.1089f, 5545.5454f, + 5913.9531f, 332.1463f, 433.0623f, 992.1605f, 1254.8217f, 1498.4819f, 1824.6357f, + 2118.3374f, 2444.6484f, 2684.8369f, 2930.4683f, 3557.4851f, 4292.9014f, 4786.7251f, + 5138.2168f, 5616.2739f, 5996.8369f, 281.7202f, 372.7708f, 1074.7051f, 1443.0428f, + 1687.6460f, 1980.7075f, 2275.4241f, 2632.2017f, 2848.1765f, 3118.7881f, 3628.5857f, + 4522.9585f, 4876.2163f, 5177.2739f, 5600.6675f, 5960.9634f, 412.0151f, 535.6881f, + 768.8618f, 1462.2601f, 1789.1055f, 1947.8196f, 2224.6890f, 2447.9089f, 2834.6140f, + 3472.6721f, 3729.8525f, 4008.2893f, 4525.7271f, 4822.9194f, 5204.6611f, 5895.0942f, + 263.8760f, 379.7789f, 825.0498f, 1113.1218f, 1465.8749f, 1846.7463f, 2146.0496f, + 2487.2766f, 2845.8447f, 3388.4800f, 3883.8447f, 4440.7603f, 4867.0815f, 5214.7280f, + 5535.8149f, 5906.9932f, 409.8116f, 583.7237f, 859.1983f, 1172.0491f, 1377.6473f, + 1984.8322f, 2361.7292f, 2688.9368f, 3238.6563f, 3542.6716f, 3944.3005f, 4441.0840f, + 4881.1211f, 5224.6045f, 5604.3711f, 5909.3657f, 318.0743f, 438.8244f, 852.9153f, + 1061.4503f, 1290.7609f, 1552.5408f, 2053.1118f, 2373.2883f, 2926.1560f, 3452.9551f, + 4098.6626f, 4585.2773f, 4967.0898f, 5271.2720f, 5644.6709f, 5961.9585f, 370.3631f, + 496.5860f, 932.6390f, 1213.4189f, 1452.6641f, 1803.1532f, 2092.2354f, 2607.5247f, + 2883.8086f, 3112.1086f, 3687.5657f, 4525.1274f, 4846.9404f, 5130.0537f, 5416.4141f, + 5804.5122f, 247.8941f, 343.9862f, 751.6780f, 1526.2566f, 1712.5012f, 2038.0667f, + 2324.0371f, 2727.9749f, 3005.8975f, 3378.9817f, 3858.2002f, 4339.2017f, 4716.4580f, + 5125.0918f, 5564.3589f, 5969.7163f, 297.6552f, 401.7544f, 891.9346f, 1380.2275f, + 1540.3125f, 1782.6058f, 2009.2045f, 2614.2092f, 2899.5396f, 3379.9722f, 3804.1169f, + 4284.8540f, 4696.3335f, 5118.4551f, 5525.9839f, 5934.2686f, 226.1444f, 333.4511f, + 682.9995f, 1307.4166f, 1554.1943f, 1849.3679f, 2116.3438f, 2756.3567f, 3204.3018f, + 3540.4106f, 4002.1895f, 4402.7734f, 4796.4395f, 5192.6812f, 5600.6841f, 5960.1855f, + 196.3791f, 299.9716f, 572.3173f, 1201.8826f, 1804.7235f, 2012.0171f, 2264.7415f, + 2790.3406f, 3272.6926f, 3668.4863f, 4063.0435f, 4442.4419f, 4810.5957f, 5156.0923f, + 5512.8501f, 5900.7441f, 280.1911f, 391.5190f, 705.9903f, 1435.5063f, 1588.2345f, + 2116.5032f, 2357.1875f, 2670.7461f, 3299.0071f, 3507.9336f, 4044.3057f, 4591.9023f, + 4981.4575f, 5281.1270f, 5654.7158f, 5949.9263f, 262.5740f, 370.5089f, 654.7243f, + 1278.9299f, 1847.3096f, 2087.3394f, 2553.8892f, 2887.8269f, 3254.0747f, 3810.6626f, + 4258.4390f, 4528.8022f, 4872.9741f, 5206.0483f, 5565.2876f, 5918.5596f, 193.6133f, + 356.3127f, 1076.8109f, 1485.8608f, 1887.7994f, 2273.1333f, 2676.7832f, 3052.3513f, + 3419.1294f, 3792.5024f, 4161.7036f, 4532.6431f, 4898.5176f, 5262.0498f, 5622.8901f, + 5976.4863f, 302.7377f, 409.7598f, 899.1851f, 1176.6501f, 1531.3615f, 1933.6494f, + 2229.9561f, 2819.8936f, 3031.6248f, 3807.0129f, 4118.7495f, 4412.7339f, 4704.6758f, + 5012.0190f, 5351.4160f, 5892.3232f, 421.1889f, 587.3521f, 835.9208f, 1248.0127f, + 1475.8882f, 1779.3772f, 2330.6294f, 2606.6780f, 3026.0417f, 3513.8035f, 3754.6023f, + 4081.0518f, 4536.3438f, 4815.9336f, 5117.6392f, 5802.9902f, 378.0719f, 722.0884f, + 1327.5808f, 1665.8940f, 1954.7782f, 2238.9473f, 2608.8538f, 2958.7910f, 3341.5112f, + 3721.2021f, 4095.8457f, 4457.6865f, 4843.8672f, 5212.5142f, 5589.5122f, 5945.3730f, + 468.4631f, 962.3222f, 1541.0238f, 1919.1746f, 2347.4365f, 2650.7366f, 2927.5945f, + 3166.4202f, 3451.0664f, 3757.8477f, 4109.2383f, 4467.9443f, 4858.6045f, 5211.8428f, + 5593.3311f, 5951.0137f, 422.2508f, 845.8956f, 1495.2552f, 1811.3933f, 2128.1157f, + 2371.2532f, 2656.0715f, 2942.9011f, 3294.5308f, 3652.0935f, 4031.2534f, 4399.2222f, + 4801.9497f, 5163.3721f, 5559.4517f, 5934.4063f, 423.1028f, 661.7286f, 991.1974f, + 1204.3813f, 1472.8564f, 2003.0298f, 2443.5833f, 2789.2795f, 3354.1692f, 3722.7822f, + 4032.7351f, 4320.9727f, 4621.8140f, 4963.7310f, 5429.8203f, 5900.1465f, 361.2513f, + 485.9720f, 828.4865f, 1340.9952f, 1497.8477f, 2072.8511f, 2437.9839f, 2674.9912f, + 3259.3357f, 3539.0474f, 3789.1389f, 4087.5015f, 4404.8867f, 4771.0947f, 5500.2227f, + 6015.7041f, 301.8146f, 392.9569f, 685.1938f, 1783.6246f, 2034.8542f, 2257.1614f, + 2519.8713f, 2782.6279f, 3152.1135f, 3400.8662f, 3614.3801f, 3906.7375f, 4233.1968f, + 4712.3682f, 5596.0396f, 5998.5742f, 242.0591f, 371.0809f, 729.0743f, 1190.6813f, + 1851.5691f, 2132.6724f, 2334.7773f, 2522.3608f, 3091.8643f, 3621.4614f, 3854.5227f, + 4174.7017f, 4490.7510f, 4780.1230f, 5157.6147f, 5865.4756f, 431.2477f, 562.1808f, + 888.5207f, 1034.2062f, 1443.2480f, 2109.8850f, 2337.1443f, 2829.1870f, 3070.1301f, + 3252.6370f, 3510.3967f, 4366.2236f, 4843.2139f, 5133.0537f, 5549.8911f, 5850.3252f, + 420.2594f, 668.9339f, 911.1281f, 1218.0372f, 1806.5541f, 2050.8423f, 2394.5708f, + 2761.3542f, 3021.1716f, 3414.0020f, 3970.9626f, 4342.2900f, 4691.6074f, 5062.5386f, + 5452.6655f, 5792.8384f, 257.3011f, 370.8905f, 604.8825f, 1096.4209f, 1711.8464f, + 1934.4335f, 2319.4717f, 2769.0144f, 3019.0200f, 3354.3726f, 4119.8809f, 4354.8589f, + 4557.7979f, 4893.5776f, 5450.3042f, 5910.4136f, 241.4264f, 347.9253f, 622.2432f, + 1248.8121f, 1559.7318f, 1848.8098f, 2315.5635f, 2571.5894f, 2879.5754f, 3624.1069f, + 3968.0334f, 4238.9727f, 4713.4746f, 5156.6792f, 5568.5596f, 5975.8716f, 478.7131f, + 629.4184f, 918.1857f, 1342.7815f, 1535.1541f, 1803.0487f, 2483.7764f, 2724.4321f, + 2998.1257f, 3634.9932f, 3915.9443f, 4119.2837f, 4327.0283f, 4980.3516f, 5532.6880f, + 5964.3052f, 265.7818f, 373.8575f, 723.3755f, 1186.0619f, 1509.2827f, 2064.2075f, + 2298.1992f, 2566.4395f, 2785.7659f, 3423.1396f, 3883.9011f, 4136.8940f, 4463.0386f, + 5010.6592f, 5539.0337f, 5931.4414f, 221.4221f, 347.7610f, 707.4465f, 1187.0800f, + 1575.9095f, 1824.3983f, 1979.3307f, 2299.3174f, 2967.6799f, 3472.3381f, 3955.8469f, + 4292.6079f, 4794.8745f, 5127.5181f, 5652.6729f, 5953.0132f, 397.2769f, 510.2605f, + 746.8268f, 1588.0735f, 1991.5200f, 2150.6843f, 2439.0486f, 2712.2754f, 2972.5825f, + 3501.2673f, 3917.5459f, 4143.6069f, 4443.4414f, 4829.1929f, 5490.0376f, 6028.3794f, + 280.5184f, 370.6464f, 640.7120f, 1721.3899f, 1948.9806f, 2149.9592f, 2400.4678f, + 2674.0542f, 3146.3154f, 3419.8850f, 3813.9553f, 4417.4497f, 4818.3652f, 5139.6323f, + 5465.0669f, 5879.7183f, 325.2418f, 431.2627f, 1008.7708f, 1271.9235f, 1527.4150f, + 2066.6370f, 2242.3311f, 2883.4065f, 3180.6614f, 3352.5015f, 3756.9688f, 4386.6904f, + 4857.6621f, 5189.2212f, 5514.7573f, 5856.8086f, 451.8427f, 582.4401f, 925.8821f, + 1363.4249f, 1503.2460f, 1961.5940f, 2265.6001f, 2574.4414f, 3123.0769f, 3345.1587f, + 3634.3022f, 4266.0137f, 4880.8052f, 5223.5776f, 5567.8901f, 5880.3770f, 411.0873f, + 553.3847f, 809.2106f, 1023.4841f, 1189.0618f, 1786.0770f, 2121.8489f, 2454.6458f, + 2947.4700f, 3220.3210f, 3828.0911f, 4218.0229f, 4831.2383f, 5322.1445f, 5727.3906f, + 6033.3887f, 310.5608f, 442.2204f, 742.7755f, 1097.5740f, 1340.9608f, 1854.4385f, + 2261.6399f, 2634.8315f, 3297.8879f, 3638.6956f, 3925.8770f, 4232.9146f, 4559.9287f, + 4893.5830f, 5403.0981f, 5917.7056f, 377.5583f, 488.4103f, 945.2491f, 1234.1572f, + 1416.0774f, 1666.5979f, 1932.9910f, 2746.2000f, 2997.4753f, 3216.6152f, 3559.3999f, + 3843.8130f, 4359.6626f, 5014.2920f, 5560.6162f, 5992.7212f, 285.2173f, 389.6116f, + 825.5790f, 1238.8229f, 1459.6588f, 1860.8855f, 2178.6296f, 2519.1597f, 2828.0032f, + 3278.8101f, 3560.8286f, 4142.0552f, 4691.0698f, 5117.7778f, 5558.7944f, 5954.6680f, + 465.7002f, 631.7491f, 914.5521f, 1340.0057f, 1562.5760f, 1844.1741f, 2186.1208f, + 2483.7080f, 2901.9417f, 3190.3162f, 3474.7651f, 3873.4065f, 4240.1973f, 4761.1255f, + 5428.2832f, 5958.5273f, 340.5456f, 449.2341f, 793.7005f, 1387.7467f, 1555.8701f, + 1938.7877f, 2201.6155f, 2579.5762f, 2914.9724f, 3149.8584f, 3699.3984f, 3985.6790f, + 4331.7534f, 4999.4805f, 5514.6924f, 5969.4897f, 395.8350f, 564.1188f, 774.8214f, + 1276.3201f, 1721.8716f, 1864.0143f, 2267.5696f, 2790.2031f, 3003.9434f, 3377.6140f, + 3917.7395f, 4167.3867f, 4465.2529f, 4936.1138f, 5464.0479f, 5905.0444f, 324.1844f, + 443.0006f, 728.8958f, 1398.6589f, 1584.1820f, 1923.8724f, 2348.0903f, 2561.5554f, + 3154.5991f, 3449.1746f, 3771.7927f, 4182.1899f, 4937.0791f, 5361.6509f, 5727.7656f, + 6002.7505f, 267.1790f, 373.7663f, 703.5949f, 1173.7009f, 1390.2002f, 1905.7941f, + 2177.4961f, 2703.2627f, 3022.9121f, 3308.9612f, 3798.5823f, 4187.1533f, 4703.2163f, + 5136.0918f, 5571.1655f, 5966.6577f, 272.9294f, 399.3804f, 797.7335f, 1180.1516f, + 1426.4850f, 2097.2839f, 2355.4727f, 2793.8774f, 3137.1907f, 3458.7727f, 3893.6628f, + 4245.8047f, 4652.3794f, 5106.5293f, 5568.1885f, 5948.3169f, 324.5529f, 431.7663f, + 759.6147f, 1494.8739f, 1668.8168f, 2110.5635f, 2427.4104f, 2672.9270f, 3170.5266f, + 3448.2080f, 3717.1240f, 4034.2280f, 4375.3647f, 5041.1372f, 5666.9517f, 6014.7217f, + 306.4759f, 404.5361f, 795.7795f, 1675.9967f, 1835.0950f, 2160.6624f, 2430.8855f, + 2734.2646f, 3270.1426f, 3586.1355f, 3821.9670f, 4102.0078f, 4372.9404f, 4918.9146f, + 5412.0376f, 5868.5225f, 421.3803f, 607.7995f, 813.0241f, 1286.8525f, 1827.2451f, + 2026.8683f, 2333.9453f, 2730.9817f, 2988.4067f, 3303.8513f, 3759.1897f, 4057.5264f, + 4441.5493f, 4890.0078f, 5212.0469f, 5672.2188f, 423.8560f, 599.5201f, 829.0651f, + 1082.6381f, 1245.9272f, 1623.7075f, 2453.0420f, 2855.6631f, 3171.3855f, 3475.5881f, + 3715.4219f, 3972.1326f, 4419.1597f, 4894.0283f, 5363.8691f, 5919.2681f, 441.2789f, + 634.8879f, 921.6287f, 1189.0240f, 1368.7466f, 2012.1312f, 2383.7656f, 2638.5222f, + 2975.0288f, 3163.6150f, 3433.9958f, 3838.9917f, 4186.6426f, 4856.8477f, 5559.1196f, + 5977.2290f, 349.2039f, 466.2342f, 724.2582f, 904.4043f, 1190.4492f, 1981.7565f, + 2226.5554f, 2592.5098f, 2865.5525f, 3195.8196f, 3735.6345f, 4267.1660f, 4810.9893f, + 5207.5093f, 5605.1445f, 5952.0361f, 497.7713f, 719.9073f, 925.0815f, 1146.3021f, + 1326.7095f, 1574.5039f, 2306.7678f, 2714.8022f, 2967.5190f, 3400.1121f, 3732.0544f, + 3981.7878f, 4553.4819f, 5090.0869f, 5426.2085f, 5833.5220f, 471.7526f, 648.3213f, + 902.1542f, 1245.7086f, 1423.3403f, 1701.1757f, 2125.8530f, 2407.0481f, 2969.5583f, + 3294.1296f, 3712.8398f, 4140.7930f, 4808.4668f, 5322.3896f, 5662.1255f, 5950.6211f, + 345.3843f, 485.9887f, 841.2579f, 1035.9401f, 1244.8905f, 1488.1833f, 2340.4253f, + 2607.0859f, 2845.4153f, 3223.1768f, 3557.0696f, 4119.7944f, 4666.8896f, 5145.8589f, + 5565.7534f, 5976.6875f, 332.4270f, 427.5984f, 829.9191f, 1138.0469f, 1339.4468f, + 1589.0535f, 1926.0630f, 2432.9331f, 2699.7964f, 3311.4355f, 3716.1003f, 4270.4990f, + 4760.3647f, 5208.3950f, 5619.2080f, 5971.2715f, 249.0114f, 381.2982f, 925.7067f, + 1520.3356f, 1842.8396f, 2368.2908f, 2783.4033f, 3272.5757f, 3673.7402f, 4046.3950f, + 4370.4966f, 4688.0269f, 5002.6772f, 5316.3594f, 5650.2192f, 5977.6587f, 263.3275f, + 451.6255f, 1252.2307f, 1503.0652f, 1786.7695f, 2082.7554f, 2451.1829f, 2804.7590f, + 3116.7583f, 3493.8892f, 3884.6575f, 4349.6724f, 4770.0156f, 5143.1636f, 5542.5913f, + 5931.5522f, 252.9447f, 341.5762f, 632.7664f, 1766.8096f, 2084.1511f, 2272.7332f, + 2531.1006f, 2765.2080f, 3134.5417f, 3380.6223f, 3640.8015f, 3932.7854f, 4532.1172f, + 5245.2070f, 5597.0776f, 5973.6831f, 234.9979f, 324.6731f, 1239.8643f, 1663.1921f, + 1858.7769f, 2171.1614f, 2403.8818f, 2680.6433f, 2836.4985f, 3192.6577f, 3864.8811f, + 4385.8066f, 4845.9766f, 5150.2412f, 5631.1519f, 6011.7773f, 284.5302f, 410.1263f, + 985.4119f, 1298.3987f, 1789.4304f, 1996.9287f, 2450.8525f, 2831.6011f, 2994.2073f, + 3214.1306f, 3525.0498f, 3819.9141f, 4672.7544f, 5424.3545f, 5691.0732f, 5980.3096f, + 244.2704f, 415.5891f, 1038.3009f, 1317.5186f, 1686.4528f, 2081.3147f, 2476.9873f, + 2959.5393f, 3214.9561f, 3569.1431f, 3934.4736f, 4308.7114f, 4728.3687f, 5105.7964f, + 5488.1938f, 5908.9443f, 335.8417f, 468.3464f, 1003.6253f, 1275.0145f, 1534.2854f, + 1985.3167f, 2348.3411f, 2743.3169f, 2956.0967f, 3408.5063f, 3866.8574f, 4287.0034f, + 4556.7222f, 4922.7832f, 5259.7480f, 5800.2876f, 388.2726f, 518.0591f, 832.5999f, + 1325.0247f, 1528.8624f, 1808.1732f, 2151.0820f, 2486.1331f, 2815.4980f, 3158.5391f, + 3635.3606f, 3960.5383f, 4671.7686f, 5371.8140f, 5777.8940f, 6056.4722f, 506.5153f, + 673.0771f, 900.0349f, 1154.2124f, 1378.2689f, 1786.9409f, 2081.9631f, 2398.6965f, + 2859.7441f, 3075.4841f, 3546.6563f, 4322.6694f, 4732.0049f, 4992.5542f, 5267.5859f, + 5807.1812f, 487.2466f, 653.6116f, 968.5656f, 1389.2708f, 1601.5822f, 1910.9694f, + 2282.4038f, 2608.7063f, 3032.6233f, 3361.9692f, 3629.8552f, 3908.8335f, 4318.4009f, + 4646.5781f, 5043.5962f, 5792.7393f, 432.8733f, 591.7551f, 899.2619f, 1490.1176f, + 1789.8751f, 2060.3750f, 2434.8779f, 2840.3374f, 3122.1292f, 3472.8079f, 3830.8870f, + 4097.2622f, 4353.5464f, 4650.2075f, 4981.5752f, 5482.9565f, 378.4767f, 508.5656f, + 802.8280f, 947.2892f, 1532.0898f, 2038.8177f, 2349.1965f, 2650.2039f, 2863.8018f, + 3591.6697f, 3918.9211f, 4256.6255f, 4604.8467f, 4899.0996f, 5237.6084f, 5791.5029f, + 407.0908f, 546.0364f, 866.1215f, 1098.6927f, 1347.2009f, 1657.1525f, 1965.5845f, + 2717.7190f, 3033.4961f, 3509.9031f, 3873.4150f, 4131.4438f, 4389.5693f, 4774.2295f, + 5450.1768f, 5977.5151f, 429.3459f, 568.8134f, 903.5659f, 1099.2942f, 1379.4979f, + 2207.5940f, 2479.9919f, 2780.9072f, 3206.3960f, 3425.4084f, 3682.5911f, 3950.1941f, + 4324.0840f, 4689.4922f, 5068.2534f, 5787.2852f, 371.9443f, 524.7249f, 890.0464f, + 1670.7485f, 1958.5308f, 2182.7007f, 2558.5007f, 2835.4937f, 3192.0740f, 3634.4817f, + 3950.0942f, 4259.6953f, 4628.0049f, 4999.1616f, 5364.9893f, 5801.6855f, 323.1922f, + 451.0327f, 787.1655f, 1011.6555f, 1323.8138f, 2177.6636f, 2401.1392f, 2826.8796f, + 3432.8999f, 3653.1851f, 3883.9897f, 4082.7559f, 4361.6753f, 4635.1475f, 5084.7544f, + 5823.3062f, 377.0061f, 524.2181f, 743.6288f, 1378.9187f, 1857.6434f, 2056.4695f, + 2453.7949f, 2902.1995f, 3127.2651f, 3463.3523f, 3980.1316f, 4241.2578f, 4528.5859f, + 4881.4521f, 5239.3145f, 5580.5986f, 308.7965f, 403.7058f, 705.9506f, 1823.8571f, + 2126.9387f, 2369.2810f, 2647.2048f, 2855.8276f, 3209.7708f, 3498.2310f, 3747.6047f, + 3972.8647f, 4254.3325f, 4574.4292f, 5087.3965f, 5890.4219f, 274.7571f, 383.7251f, + 573.6029f, 1142.8372f, 2151.7173f, 2558.8972f, 2751.9468f, 2987.4412f, 3234.3350f, + 3526.0127f, 3922.9927f, 4189.0249f, 4483.3774f, 4877.1860f, 5396.7798f, 5921.8125f, + 248.5916f, 423.6264f, 1260.9626f, 1696.0492f, 1972.9108f, 2298.5972f, 2592.9307f, + 2947.2292f, 3266.2227f, 3614.3572f, 3980.3892f, 4359.4067f, 4770.2842f, 5158.9058f, + 5554.6597f, 5936.9043f, 320.5471f, 429.6766f, 657.1440f, 1390.1080f, 2194.6426f, + 2507.6086f, 2712.3662f, 2980.3408f, 3216.1682f, 3544.8467f, 3956.9790f, 4227.5308f, + 4463.7563f, 4745.7124f, 5088.6650f, 5525.8516f, 245.5478f, 520.3131f, 1177.0693f, + 1454.0125f, 1770.2620f, 2160.8779f, 2551.2700f, 2950.2324f, 3326.8621f, 3710.4624f, + 4104.3936f, 4481.9971f, 4865.9736f, 5230.6396f, 5608.5649f, 5965.6162f, 514.5864f, + 956.9897f, 1287.9597f, 1520.3473f, 1802.0631f, 2116.4980f, 2509.8552f, 2865.9822f, + 3238.7510f, 3611.3108f, 4016.4353f, 4431.8457f, 4860.3442f, 5231.4814f, 5614.6016f, + 5963.9976f, 537.0523f, 932.2803f, 1380.2690f, 1709.4702f, 2079.9902f, 2446.4014f, + 2859.4204f, 3229.6975f, 3623.4031f, 4012.5327f, 4373.7568f, 4724.3359f, 5078.2686f, + 5397.6040f, 5721.9639f, 6028.1167f, 452.5153f, 798.2777f, 1099.3080f, 1317.0807f, + 1652.6885f, 2059.7708f, 2471.0164f, 2808.5396f, 3146.5076f, 3494.0779f, 3870.6912f, + 4310.8281f, 4777.5024f, 5181.2617f, 5574.4912f, 5934.3813f, 340.3716f, 430.5102f, + 872.3513f, 1636.3792f, 1772.8615f, 2074.0161f, 2295.1008f, 2693.0037f, 3177.7710f, + 3391.7559f, 3670.8718f, 4224.3926f, 4896.3877f, 5199.9883f, 5580.4512f, 5911.7671f, + 317.8269f, 414.8185f, 881.1970f, 1658.4944f, 1852.0098f, 2136.0415f, 2380.8228f, + 2668.9141f, 3046.8027f, 3299.0051f, 3523.0593f, 3758.9412f, 4116.9063f, 5061.2124f, + 5624.1777f, 5989.4761f, 374.0671f, 488.0840f, 734.0546f, 1415.9261f, 1648.7783f, + 1852.8462f, 2099.1895f, 2347.5562f, 2954.8359f, 3269.6714f, 3536.7920f, 4116.1743f, + 4481.4355f, 4913.8838f, 5467.2817f, 5909.8779f, 340.4291f, 448.5775f, 1041.4979f, + 1426.0011f, 1637.8165f, 1968.6743f, 2210.7976f, 2647.5144f, 2913.8650f, 3131.7698f, + 3429.8755f, 3722.6763f, 4104.6479f, 4969.0093f, 5574.2231f, 5978.2070f, 254.2538f, + 412.7710f, 947.8206f, 1209.3683f, 1690.4813f, 2040.7881f, 2401.4314f, 2728.0066f, + 3016.2290f, 3530.3865f, 3964.6563f, 4393.6934f, 4804.2168f, 5187.9302f, 5586.4399f, + 5954.8950f, 241.0244f, 347.0750f, 835.2348f, 1601.9089f, 1786.4336f, 2134.3950f, + 2396.0139f, 2848.9712f, 3239.9138f, 3623.8250f, 4029.5088f, 4400.3936f, 4797.3564f, + 5195.7310f, 5596.6689f, 5965.9878f, 309.3683f, 453.6776f, 812.9343f, 1125.9915f, + 1423.5935f, 2149.2227f, 2514.9277f, 3031.3599f, 3463.7219f, 3790.7839f, 4064.0039f, + 4297.9839f, 4653.4551f, 5189.7061f, 5721.2954f, 6033.0752f, 469.4284f, 730.1902f, + 973.0643f, 1170.5016f, 1572.2559f, 2084.2769f, 2567.8604f, 2963.4592f, 3286.9617f, + 3580.3228f, 3882.8706f, 4335.5483f, 4859.7197f, 5258.2827f, 5627.9785f, 5957.8623f, + 454.6165f, 795.2360f, 1078.7705f, 1294.9473f, 1761.6650f, 2235.2788f, 2695.8455f, + 3095.7695f, 3473.4897f, 3833.0889f, 4185.7290f, 4528.9863f, 4893.0039f, 5240.7627f, + 5608.8594f, 5951.0718f, 563.4587f, 875.8987f, 1139.0026f, 1378.2317f, 1855.7401f, + 2279.7683f, 2651.3079f, 2968.4397f, 3279.4453f, 3607.2500f, 3975.5796f, 4358.3574f, + 4768.7969f, 5135.3706f, 5525.3501f, 5904.2617f, 461.7852f, 855.0644f, 1367.4387f, + 1702.5593f, 2141.0093f, 2500.9055f, 2853.8596f, 3123.9744f, 3406.0178f, 3694.0481f, + 4028.9985f, 4373.1113f, 4768.2891f, 5137.6895f, 5541.3721f, 5921.4507f, 438.6031f, + 753.0179f, 1269.3203f, 1630.4396f, 2027.2959f, 2350.9695f, 2672.1396f, 2957.1809f, + 3250.1545f, 3546.5315f, 3894.0161f, 4249.9346f, 4666.2266f, 5061.2524f, 5490.7749f, + 5904.6362f, 543.3182f, 828.4835f, 1239.1818f, 1471.1134f, 1737.8622f, 2037.2484f, + 2434.5112f, 2801.3242f, 3162.3250f, 3508.1255f, 3849.0903f, 4165.7588f, 4588.3809f, + 5020.0952f, 5475.2813f, 5904.6377f, 519.5982f, 837.6639f, 1171.2003f, 1363.0320f, + 1617.4617f, 1976.1787f, 2472.0303f, 2901.3264f, 3340.7300f, 3736.0830f, 4103.3843f, + 4444.8657f, 4800.9482f, 5145.6011f, 5544.2002f, 5933.0981f, 433.3774f, 582.7663f, + 899.6142f, 1150.7437f, 1321.1309f, 1947.8643f, 2557.8604f, 2733.1497f, 3240.4907f, + 3634.7915f, 3855.9856f, 4058.0281f, 4364.2568f, 5096.5225f, 5659.0952f, 6013.8145f, + 424.9731f, 604.3164f, 868.1793f, 1207.7882f, 1414.2374f, 1713.2893f, 2520.2900f, + 2960.8887f, 3210.8542f, 3584.5403f, 3914.5796f, 4149.8550f, 4505.7705f, 4886.9575f, + 5214.5361f, 5597.8389f, 347.0334f, 494.2440f, 753.7191f, 1451.0435f, 1700.7461f, + 1925.4844f, 2605.7988f, 2870.4744f, 3173.7312f, 3758.7219f, 4112.1929f, 4400.3882f, + 4866.1016f, 5165.8799f, 5433.0371f, 5781.1509f, 318.4942f, 464.3939f, 783.5214f, + 1491.0234f, 1708.4984f, 2280.2876f, 2533.3354f, 2885.1736f, 3443.7451f, 3669.8506f, + 4000.6792f, 4269.6626f, 4571.2739f, 4827.2158f, 5277.3813f, 5850.4736f, 386.8698f, + 519.0056f, 725.0029f, 981.5649f, 1156.1665f, 1500.4691f, 2421.7993f, 2962.4722f, + 3175.0166f, 3548.4756f, 3860.7961f, 4146.4150f, 4658.9897f, 5088.3999f, 5531.8945f, + 5951.4624f, 315.9294f, 738.5538f, 1171.9581f, 1553.7167f, 1949.9159f, 2319.6641f, + 2707.5493f, 3069.2996f, 3444.6157f, 3811.2139f, 4177.5469f, 4545.6943f, 4905.0444f, + 5271.3926f, 5622.6831f, 5974.4141f, 216.5136f, 598.1122f, 1059.3214f, 1466.4785f, + 1880.1747f, 2263.6533f, 2658.3081f, 3030.4099f, 3413.6802f, 3780.1853f, 4157.1455f, + 4519.1919f, 4893.5439f, 5244.3530f, 5603.1064f, 5926.8379f, 375.4021f, 487.0890f, + 844.4013f, 1574.3596f, 1794.5249f, 2106.2878f, 2418.5217f, 2657.8938f, 3116.6096f, + 3457.8625f, 3691.0596f, 3930.1062f, 4259.5928f, 4592.4370f, 5020.5078f, 5840.3989f, + 474.3148f, 724.2144f, 974.0716f, 1283.4182f, 1521.2632f, 1746.4248f, 2333.0957f, + 2874.2966f, 3111.9636f, 3440.0410f, 3752.9678f, 3975.7139f, 4294.7056f, 4821.9893f, + 5201.5562f, 5658.8301f, 400.0291f, 564.9626f, 808.2393f, 1083.2745f, 1300.4403f, + 2080.7405f, 2588.6882f, 2858.4629f, 3206.4502f, 3429.8623f, 3746.9080f, 4341.4868f, + 4713.2803f, 4986.4258f, 5336.7339f, 5710.1123f, 354.4416f, 480.1495f, 834.1089f, + 1037.7775f, 1350.0652f, 1791.1736f, 2193.0159f, 2504.6775f, 2776.0623f, 3153.0994f, + 4108.1357f, 4597.4082f, 4861.9688f, 5092.8613f, 5473.2295f, 5932.0332f, 237.3935f, + 346.9133f, 675.5335f, 1481.0535f, 1716.8414f, 1884.7153f, 2099.3057f, 2725.5403f, + 3022.8506f, 3276.2922f, 3639.1001f, 4185.3926f, 4941.6597f, 5292.0093f, 5682.0391f, + 5981.0215f, 367.4981f, 469.7130f, 820.7811f, 1219.7736f, 1368.4479f, 1624.6671f, + 1804.2581f, 2607.8589f, 2891.3174f, 3212.2432f, 3760.7290f, 4015.6111f, 4618.0068f, + 5129.3213f, 5652.1582f, 6042.1113f, 312.6796f, 415.8322f, 674.1500f, 853.7709f, + 1808.7385f, 2232.5310f, 2497.8157f, 2834.2991f, 3039.7012f, 3301.4050f, 3659.2969f, + 4455.9453f, 4841.4912f, 5111.6167f, 5502.2534f, 5924.6357f, 341.9309f, 471.7513f, + 758.1926f, 979.7221f, 1287.4463f, 1737.0303f, 2160.7915f, 2664.5562f, 2961.8315f, + 3461.7439f, 3732.6611f, 4109.0928f, 4568.9111f, 5037.4331f, 5511.3169f, 5966.1304f, + 351.3721f, 462.1897f, 765.1075f, 946.3102f, 1322.8093f, 2292.2400f, 2503.6494f, + 2819.7234f, 3079.2803f, 3297.6252f, 3571.4668f, 3872.0823f, 4337.6426f, 5079.1504f, + 5562.8110f, 5942.7153f, 435.4323f, 614.4746f, 892.8980f, 1215.9469f, 1395.9762f, + 1814.3936f, 2155.9590f, 2465.0427f, 3201.6211f, 3490.9224f, 3853.2620f, 4410.1855f, + 4786.0625f, 5095.0181f, 5394.4805f, 5715.3364f, 294.6053f, 417.1553f, 1046.2922f, + 1443.0247f, 1636.7180f, 1956.4248f, 2189.9697f, 2869.8071f, 3129.9385f, 3462.5681f, + 3895.2805f, 4213.4541f, 4541.8950f, 5009.1958f, 5472.7642f, 5983.0063f, 322.1185f, + 446.8733f, 689.4188f, 1338.2788f, 1643.1023f, 1903.8652f, 2494.2722f, 2804.6968f, + 3103.8682f, 3640.1233f, 3965.9861f, 4172.5596f, 4404.7388f, 4670.7544f, 5240.3682f, + 5893.4600f, 209.7024f, 336.5508f, 729.0126f, 1217.3285f, 1699.0111f, 1891.2837f, + 2146.8486f, 2830.0850f, 3108.6204f, 3446.0396f, 3754.1230f, 3945.1038f, 4474.5806f, + 5191.6987f, 5613.3076f, 5970.2695f, 346.6580f, 470.5094f, 663.3455f, 1266.9061f, + 2020.5759f, 2270.5173f, 2527.3550f, 2826.9104f, 3078.3403f, 3401.2625f, 3804.3770f, + 4100.3091f, 4407.7876f, 4732.2319f, 5150.2749f, 5808.2559f, 283.7796f, 391.4603f, + 1165.6863f, 1456.1125f, 1692.9001f, 2008.4825f, 2322.7837f, 2784.0608f, 2998.5811f, + 3268.5164f, 3548.9373f, 4167.1289f, 4643.9878f, 5099.2881f, 5473.0781f, 5929.8242f, + 301.0849f, 383.1578f, 692.0848f, 1648.9374f, 1873.0947f, 2109.6113f, 2345.0110f, + 2613.1121f, 2922.0193f, 3170.0020f, 3405.0774f, 3881.9875f, 4778.3154f, 5092.5205f, + 5445.7100f, 5920.7896f, 509.1023f, 750.8580f, 963.8820f, 1295.3452f, 1634.8796f, + 1818.7975f, 2151.1250f, 2590.3354f, 2867.5596f, 3238.7666f, 3747.2834f, 4053.8911f, + 4457.8164f, 4928.0151f, 5295.3521f, 5789.0571f, 421.8951f, 547.9814f, 967.4185f, + 1153.8607f, 1461.4230f, 1813.0994f, 2155.2703f, 2570.9712f, 2777.6597f, 3048.9863f, + 3432.0986f, 3729.3877f, 4395.7461f, 5028.7402f, 5486.4946f, 5951.5024f, 340.6758f, + 445.7014f, 931.8882f, 1253.4775f, 1521.9260f, 1969.5759f, 2267.5332f, 2735.0112f, + 2948.7678f, 3236.5166f, 3529.5505f, 3882.3674f, 4699.5781f, 5089.6641f, 5377.7842f, + 5880.7778f, 284.1882f, 408.6918f, 786.3123f, 1670.3220f, 2042.9493f, 2265.2275f, + 2691.2012f, 3035.8762f, 3334.1719f, 3863.1194f, 4276.8916f, 4571.0420f, 4996.4404f, + 5336.5205f, 5647.9556f, 5944.5996f, 300.0066f, 616.4817f, 1238.7324f, 1614.8296f, + 1997.6188f, 2367.4343f, 2784.5605f, 3168.8354f, 3569.8250f, 3965.6011f, 4336.3804f, + 4689.5874f, 5044.2012f, 5365.7456f, 5697.5654f, 6010.6572f, 242.9420f, 476.8371f, + 1250.6661f, 1671.6031f, 2159.6443f, 2637.7417f, 3049.8589f, 3371.6045f, 3674.8706f, + 3951.1006f, 4230.6416f, 4543.2827f, 4887.4478f, 5220.5581f, 5595.2686f, 5962.1313f, + 242.6795f, 331.1335f, 635.2861f, 1801.5236f, 2084.1472f, 2264.4692f, 2506.2891f, + 2799.4441f, 3236.7134f, 3489.6038f, 3859.3291f, 4424.8008f, 4964.6348f, 5298.6533f, + 5640.2031f, 5988.0552f, 254.0538f, 336.2447f, 1216.6261f, 1717.7201f, 1886.0708f, + 2176.6338f, 2405.8547f, 2762.3037f, 2934.8816f, 3167.0657f, 3385.5457f, 3804.4346f, + 4848.8198f, 5286.0352f, 5630.5391f, 6086.4492f, 295.2298f, 426.2079f, 630.7856f, + 1155.5609f, 1827.6831f, 2120.5283f, 2462.4373f, 2759.6152f, 2990.9526f, 3253.4216f, + 3910.9834f, 4204.2754f, 4462.7944f, 4909.7529f, 5579.9653f, 5985.8579f, 298.9633f, + 410.3875f, 810.1115f, 1346.1040f, 1499.2391f, 2210.3948f, 2467.9424f, 2792.7122f, + 3284.0874f, 3493.0740f, 3784.1899f, 4319.6396f, 4860.6548f, 5213.8540f, 5609.8672f, + 5949.6890f, 437.9900f, 575.3093f, 866.0077f, 1104.2080f, 1307.4966f, 1959.9323f, + 2293.9365f, 2604.6704f, 2966.6514f, 3228.0056f, 3548.8499f, 4096.4424f, 4769.5420f, + 5086.5449f, 5416.5317f, 5853.6909f, 412.4955f, 569.1867f, 864.0179f, 1117.6798f, + 1348.6332f, 1976.5171f, 2334.3960f, 2640.3381f, 3006.5347f, 3327.5784f, 3695.8564f, + 4042.1753f, 4362.7837f, 4687.4751f, 5389.8662f, 5966.5825f, 406.8686f, 542.0319f, + 867.3541f, 1436.3810f, 1678.6399f, 2000.1501f, 2358.1204f, 2651.3806f, 3042.1216f, + 3339.2766f, 3617.9963f, 3933.3860f, 4249.0278f, 4591.8530f, 5502.0400f, 6020.7910f, + 375.4336f, 519.7731f, 764.5574f, 1215.1381f, 1482.9417f, 1696.8020f, 1957.0332f, + 2169.1169f, 2973.4634f, 3687.7449f, 3966.8525f, 4258.8042f, 4680.6567f, 4947.0225f, + 5230.9824f, 5843.2466f, 443.2378f, 574.0562f, 813.3345f, 1282.7894f, 1538.0752f, + 1727.8997f, 2007.8584f, 2194.5601f, 2755.8220f, 3460.9243f, 3654.1399f, 4030.5530f, + 4572.4727f, 4904.7847f, 5400.6147f, 5934.2656f, 423.6246f, 540.1947f, 862.8629f, + 1386.7659f, 1577.2052f, 1811.0304f, 2046.7363f, 2309.0366f, 3129.1145f, 3533.0020f, + 3738.4211f, 4021.1111f, 4357.3677f, 4634.8740f, 5307.2920f, 5944.9155f, 287.7661f, + 401.5490f, 725.6079f, 950.8911f, 1186.5465f, 1490.1750f, 2114.7920f, 2562.4019f, + 3028.3977f, 3519.6277f, 3940.5737f, 4339.3086f, 4765.8188f, 5172.3428f, 5582.8022f, + 5971.0273f, 382.6039f, 537.7234f, 836.8093f, 1371.3546f, 1578.9803f, 1869.8213f, + 2292.5596f, 2540.8601f, 3032.9834f, 3402.5059f, 3737.0569f, 4053.9937f, 4446.6240f, + 5251.8457f, 5710.7935f, 6022.2925f, 313.2195f, 415.0511f, 690.6860f, 1561.4832f, + 1815.6521f, 2059.9187f, 2345.5095f, 2614.8701f, 3006.9604f, 3291.9744f, 3590.4119f, + 3996.1516f, 4365.4995f, 4853.4956f, 5465.1572f, 5954.5718f, 361.7959f, 448.4001f, + 921.3198f, 1343.1167f, 1488.6287f, 1736.7700f, 1950.8906f, 2536.0193f, 2768.7393f, + 3062.4473f, 3484.6570f, 3888.5618f, 4618.4038f, 5092.6641f, 5523.3657f, 5966.6772f, + 249.5541f, 366.6601f, 684.6592f, 1203.0931f, 1642.2089f, 1961.8837f, 2227.3289f, + 2421.1348f, 2660.5676f, 3229.5410f, 3822.5837f, 4232.7266f, 4782.5181f, 5127.2612f, + 5570.2676f, 5978.9858f, 287.4206f, 421.3210f, 704.0352f, 1279.8597f, 1562.7307f, + 2115.4241f, 2492.4517f, 2780.9470f, 3317.3616f, 3606.1492f, 4026.6375f, 4337.9014f, + 4699.6895f, 4997.2573f, 5431.1787f, 5903.8628f, 487.9554f, 740.9349f, 1021.9616f, + 1327.3262f, 1620.8544f, 1890.7717f, 2269.1218f, 2584.4868f, 2911.2896f, 3424.9221f, + 3855.1670f, 4205.9272f, 4707.2466f, 5147.1846f, 5601.1152f, 5953.4673f, 400.8269f, + 513.4500f, 786.8242f, 1269.3298f, 1441.4178f, 1696.9789f, 1911.0537f, 2223.0684f, + 2847.1619f, 3113.3845f, 3670.6318f, 4146.2900f, 4555.9204f, 5083.8579f, 5574.8120f, + 5987.6030f, 379.0329f, 487.7222f, 914.8179f, 1130.9854f, 1430.1394f, 1830.0769f, + 2088.8796f, 2613.6855f, 2803.1633f, 3457.1777f, 4032.6118f, 4306.7344f, 4662.6899f, + 4959.6348f, 5245.5234f, 5787.3940f, 340.6941f, 451.0338f, 656.2767f, 911.5805f, + 1124.9330f, 1733.8730f, 2518.7861f, 2768.6851f, 3211.3733f, 3717.7583f, 3929.6772f, + 4176.2993f, 4522.4517f, 5011.5547f, 5575.8784f, 6006.7222f, 341.5027f, 441.6417f, + 807.2695f, 1060.2080f, 1251.2837f, 1478.9895f, 1750.0796f, 2594.8977f, 2924.5027f, + 3401.4751f, 3852.0557f, 4292.4683f, 4718.2930f, 5159.4775f, 5562.4067f, 5972.5571f, + 313.8985f, 421.5380f, 667.2407f, 873.6023f, 1110.1119f, 2060.7332f, 2381.0916f, + 2746.2288f, 3080.5649f, 3399.9905f, 3897.5884f, 4434.9990f, 5048.1343f, 5390.8149f, + 5744.3931f, 6007.9326f, 252.1832f, 354.2392f, 673.5427f, 1339.1161f, 1554.8853f, + 2014.9351f, 2300.4138f, 2829.6182f, 3213.1714f, 3409.5105f, 3604.3242f, 3927.8020f, + 4622.3218f, 5103.4565f, 5559.5024f, 5971.5986f, 385.2648f, 513.7607f, 760.7678f, + 983.5819f, 1175.7727f, 2134.7810f, 2592.9614f, 2822.0161f, 3232.2524f, 3445.3516f, + 3750.7583f, 4094.6714f, 4401.5830f, 4753.4204f, 5549.2319f, 6034.7148f, 220.6833f, + 314.5706f, 622.2172f, 1350.8225f, 1785.5879f, 2077.5837f, 2504.2158f, 3057.6992f, + 3436.0974f, 3695.2976f, 3953.4272f, 4267.8701f, 4660.6865f, 5073.6831f, 5501.9478f, + 5929.9780f, 207.8814f, 310.4071f, 646.2098f, 1270.5835f, 1542.7271f, 2079.3804f, + 2440.0339f, 2843.4690f, 3272.4854f, 3657.9851f, 4061.2014f, 4444.9780f, 4841.6060f, + 5224.5947f, 5620.9141f, 5972.7261f, 326.1488f, 456.7737f, 740.3350f, 961.4597f, + 1262.7579f, 2190.7178f, 2483.5300f, 2872.4180f, 3328.4910f, 3811.0334f, 4153.1602f, + 4441.8271f, 4801.1802f, 5065.2988f, 5381.6309f, 5693.2886f, 206.2046f, 328.0855f, + 618.9507f, 980.9994f, 1695.9775f, 1982.3051f, 2275.5444f, 2806.0271f, 3269.5178f, + 3491.2456f, 3722.1775f, 4145.9121f, 4843.1167f, 5266.8677f, 5656.8794f, 5992.1201f, + 308.1086f, 407.7706f, 806.7985f, 1045.7629f, 1401.8912f, 2108.3472f, 2331.7849f, + 2952.5391f, 3174.1865f, 3374.0686f, 3645.4260f, 4292.7183f, 4939.2969f, 5250.4829f, + 5607.2358f, 5932.8657f, 267.5990f, 378.7492f, 642.2629f, 871.7917f, 1691.7523f, + 2087.5117f, 2423.1462f, 2686.1487f, 3021.7893f, 3724.0247f, 4035.5454f, 4369.5903f, + 4680.1167f, 4991.4175f, 5323.6875f, 5811.7471f, 312.3856f, 437.4281f, 714.5340f, + 899.5771f, 1632.7545f, 1938.5369f, 2295.5544f, 2625.6189f, 2900.5576f, 3295.4934f, + 3557.1260f, 3960.1123f, 4731.6079f, 5141.8447f, 5502.7793f, 5954.0049f, 332.2842f, + 449.0976f, 875.9957f, 1206.1912f, 1422.6793f, 2097.5745f, 2354.2483f, 2715.8494f, + 3093.4697f, 3344.5132f, 3623.4814f, 3889.3655f, 4256.2002f, 4994.5742f, 5593.8428f, + 5985.9575f, 286.9586f, 434.7701f, 781.3996f, 1248.3495f, 1835.5530f, 2137.1155f, + 2573.7449f, 2869.9299f, 3126.0564f, 3459.1448f, 3769.4475f, 4138.3076f, 4688.0298f, + 5084.9028f, 5436.8086f, 5894.2520f, 327.0000f, 429.0804f, 663.7327f, 849.7463f, + 1174.9340f, 2383.3875f, 2695.9597f, 2941.2026f, 3214.4724f, 3433.6287f, 3778.9312f, + 4134.8096f, 4504.8022f, 5066.7559f, 5599.2290f, 5985.7334f, 244.4052f, 499.2254f, + 1294.8232f, 1689.3677f, 2123.5024f, 2572.4958f, 3042.9067f, 3446.8752f, 3836.3740f, + 4175.6729f, 4485.3213f, 4792.3755f, 5094.9077f, 5386.1816f, 5699.6411f, 6008.2114f, + 561.9757f, 1020.3204f, 1494.1995f, 1841.8171f, 2297.0906f, 2772.6184f, 3204.8804f, + 3565.8628f, 3935.4106f, 4253.4141f, 4559.7021f, 4849.9653f, 5140.2852f, 5428.6934f, + 5731.2251f, 6023.5078f, 581.6182f, 1053.5670f, 1478.5878f, 1784.4789f, 2125.1157f, + 2454.5889f, 2809.0256f, 3141.7256f, 3490.7529f, 3848.5923f, 4201.7271f, 4568.7720f, + 4945.9619f, 5288.6289f, 5647.7642f, 5981.9341f, 258.9683f, 364.0963f, 722.5463f, + 1763.2114f, 1969.3870f, 2265.5239f, 2532.1821f, 2883.3557f, 3388.1838f, 3725.3120f, + 4080.9338f, 4390.3818f, 4716.3599f, 5068.4941f, 5452.2778f, 5847.1401f, 271.5428f, + 401.4228f, 695.5894f, 857.3072f, 1776.5358f, 2008.5603f, 2554.4143f, 2844.4021f, + 3018.6877f, 3226.1279f, 3482.3398f, 3810.6858f, 4549.3071f, 5266.2764f, 5614.6157f, + 5945.6904f, 330.3132f, 444.6271f, 669.0279f, 874.5479f, 1102.9247f, 2052.1780f, + 2436.2378f, 2711.1165f, 3037.7537f, 3298.2036f, 3898.6858f, 4241.5415f, 4606.7637f, + 5086.6919f, 5569.7397f, 5988.6797f, 232.3014f, 344.5512f, 578.5155f, 1213.9569f, + 1880.9729f, 2105.6685f, 2335.4148f, 2550.3965f, 3147.6501f, 3491.9253f, 3791.5613f, + 4159.6694f, 4642.2441f, 5103.3340f, 5605.4106f, 5989.7969f, 346.3687f, 444.8047f, + 714.3775f, 889.1195f, 1211.8463f, 2168.7598f, 2430.2490f, 2760.6326f, 3012.4961f, + 3268.8750f, 3565.1558f, 4172.5791f, 4781.5391f, 5127.6704f, 5512.6323f, 5911.3779f, + 398.0477f, 553.8537f, 845.8521f, 1119.3066f, 1309.7244f, 1928.3351f, 2351.2095f, + 2649.8230f, 3050.6750f, 3297.0566f, 3592.7275f, 3916.1785f, 4723.3325f, 5318.1221f, + 5703.9697f, 5996.7651f, 371.4409f, 471.0789f, 896.4924f, 1197.7544f, 1400.8007f, + 1611.1555f, 1867.3550f, 2818.4475f, 3002.5906f, 3250.1440f, 3546.5891f, 4265.0371f, + 4890.3369f, 5274.4722f, 5659.3560f, 5946.9644f, 330.9331f, 448.7211f, 808.3973f, + 978.2021f, 1652.6361f, 1969.0725f, 2357.0146f, 2680.4792f, 2859.9165f, 3078.9578f, + 3423.6895f, 4233.3169f, 4856.7813f, 5086.5723f, 5393.9961f, 5938.6035f, 323.9659f, + 433.8731f, 1045.5168f, 1369.1907f, 1561.9178f, 1984.2457f, 2224.0959f, 2747.3657f, + 2995.0359f, 3242.9248f, 3501.0344f, 4022.2388f, 4847.4985f, 5210.9922f, 5658.1357f, + 6005.0718f, 354.6574f, 501.6520f, 852.5305f, 1020.8707f, 1540.5925f, 1998.5675f, + 2253.1487f, 2845.3960f, 3056.5273f, 3305.0466f, 3954.2900f, 4591.7471f, 4915.2856f, + 5221.9082f, 5544.7285f, 5879.9150f, 363.1311f, 474.7310f, 907.5490f, 1106.8586f, + 1367.2662f, 1646.6934f, 2031.3650f, 2326.4382f, 2568.6519f, 3030.1091f, 3905.6482f, + 4265.9111f, 4716.1831f, 5017.0454f, 5469.8149f, 5958.6182f, 379.9262f, 524.4459f, + 845.4813f, 1275.4414f, 1458.2488f, 1772.5863f, 2067.7981f, 2526.8850f, 3066.4063f, + 3307.8713f, 3807.2900f, 4199.1509f, 4452.4653f, 4854.7471f, 5464.8833f, 5947.7842f, + 371.8218f, 483.9148f, 778.2747f, 1208.0812f, 1366.3983f, 1623.4895f, 1798.8777f, + 2224.6445f, 3103.7175f, 3386.0408f, 3782.8284f, 4307.4727f, 4698.8994f, 5118.1255f, + 5505.1919f, 5921.1724f, 217.9059f, 323.3224f, 639.7305f, 1026.5331f, 1312.9242f, + 1885.6948f, 2361.8403f, 2805.5396f, 3213.2600f, 3631.5017f, 4033.4087f, 4426.3423f, + 4821.3203f, 5208.3833f, 5590.5205f, 5956.1538f, 211.9971f, 311.2018f, 504.6345f, + 858.3289f, 1574.7019f, 1934.9866f, 2381.4163f, 2786.2043f, 3238.9326f, 3611.0518f, + 4005.2578f, 4401.0615f, 4802.1479f, 5192.5493f, 5587.1479f, 5965.5977f, 219.3884f, + 319.3835f, 604.0102f, 1114.8630f, 1481.3870f, 2036.0469f, 2303.4883f, 2616.1384f, + 3253.6335f, 3556.5107f, 3946.6567f, 4520.3555f, 5091.0479f, 5416.3037f, 5748.5737f, + 5946.5757f, 350.3716f, 515.4462f, 756.5206f, 1061.4270f, 1251.9570f, 1723.2751f, + 2687.6689f, 3036.2019f, 3273.9678f, 3744.2939f, 4098.6284f, 4391.4160f, 4917.6777f, + 5244.2852f, 5551.4976f, 5880.1572f, 311.6069f, 458.7317f, 795.9418f, 969.5021f, + 1511.2507f, 1952.5673f, 2273.6116f, 2795.8657f, 3049.7053f, 3578.0598f, 3911.1873f, + 4327.2598f, 4735.3105f, 5122.3423f, 5479.7817f, 5858.1504f, 267.8399f, 390.6757f, + 886.2357f, 1179.5110f, 1466.6409f, 2088.7725f, 2328.1262f, 2993.5786f, 3283.5256f, + 3593.2822f, 4095.7588f, 4500.4009f, 4887.5132f, 5219.0859f, 5553.4224f, 5915.6831f, + 279.2209f, 413.3200f, 648.4438f, 1282.1798f, 1793.2556f, 1952.1060f, 2484.9436f, + 2857.3630f, 3077.2114f, 3548.2585f, 4045.4526f, 4309.5947f, 4760.2900f, 5208.1948f, + 5620.9717f, 5968.3237f, 306.2321f, 424.7843f, 618.7867f, 1288.7572f, 2110.7849f, + 2346.5396f, 2582.5366f, 2833.5730f, 3074.3774f, 3464.7886f, 3984.6379f, 4262.0337f, + 4601.5132f, 4999.6992f, 5498.8926f, 5920.4814f, 259.2613f, 353.6931f, 762.5328f, + 1906.2162f, 2088.1213f, 2317.9741f, 2546.5935f, 2880.3687f, 3332.0002f, 3636.9216f, + 3946.4287f, 4226.0356f, 4502.1084f, 5007.0601f, 5496.4824f, 5924.8877f, 244.3871f, + 357.0287f, 1114.7865f, 1651.1329f, 1850.2976f, 2200.5942f, 2484.7026f, 2872.6968f, + 3092.8455f, 3373.5869f, 3707.5891f, 4180.1289f, 4603.5298f, 5132.2671f, 5554.7617f, + 5973.5220f, 700.5439f, 1363.5277f, 1745.2494f, 2081.9539f, 2379.8628f, 2623.6003f, + 2883.6484f, 3133.9824f, 3457.7092f, 3819.0100f, 4191.0537f, 4547.0400f, 4912.5127f, + 5241.3423f, 5594.9395f, 5930.6099f, 268.7704f, 370.8200f, 609.4679f, 1558.5339f, + 1961.6279f, 2155.8916f, 2419.4485f, 2655.5103f, 3152.6685f, 3426.9221f, 3716.8181f, + 4107.1616f, 4965.5698f, 5384.2026f, 5706.7183f, 6015.6196f, 305.7638f, 395.9599f, + 1103.0944f, 1383.6494f, 1612.9742f, 1915.2496f, 2189.8008f, 2555.3608f, 2720.8220f, + 3038.2434f, 3927.1301f, 4263.0518f, 4685.7217f, 4984.1377f, 5272.6162f, 5984.5376f, + 294.0385f, 426.7762f, 814.5162f, 1056.9037f, 1715.3539f, 2005.3177f, 2316.4392f, + 2647.4297f, 2893.8242f, 3196.7476f, 3720.0044f, 4186.9790f, 4840.4512f, 5290.1250f, + 5684.2139f, 5967.5859f, 359.5141f, 517.6051f, 807.4898f, 1143.5930f, 1328.1393f, + 1814.7098f, 2309.8894f, 2618.8655f, 3160.5962f, 3445.0479f, 3883.2664f, 4235.5200f, + 4718.7324f, 5367.3608f, 5765.9331f, 6034.9233f, 241.5752f, 375.5109f, 818.8776f, + 1298.7773f, 1656.9050f, 2169.8962f, 2565.1440f, 3015.9919f, 3437.9463f, 3863.8203f, + 4254.4023f, 4637.0952f, 5027.8252f, 5358.3784f, 5685.5000f, 5980.4063f, 322.5406f, + 454.9644f, 963.3659f, 1513.8885f, 1704.5070f, 2235.6599f, 2523.6467f, 2995.0757f, + 3287.8682f, 3552.8811f, 3872.4360f, 4201.2227f, 4571.9087f, 5066.6792f, 5562.1206f, + 5935.7900f, 412.5748f, 615.8419f, 1126.9519f, 1455.5172f, 1653.3076f, 1965.2689f, + 2240.6904f, 2672.5129f, 3127.3301f, 3477.8540f, 3983.6145f, 4458.6558f, 4896.7998f, + 5237.9814f, 5609.1597f, 5939.6416f, 342.1361f, 470.6100f, 958.3576f, 1195.0166f, + 1426.4667f, 1684.2009f, 2194.0950f, 2545.9453f, 2946.1851f, 3415.2820f, 3657.4158f, + 4408.6763f, 5097.2251f, 5404.2202f, 5719.9829f, 5977.7959f, 297.8767f, 386.6347f, + 1095.8346f, 1454.3085f, 1651.6417f, 1927.9633f, 2198.4927f, 2583.1694f, 2757.0144f, + 3009.6497f, 3310.9514f, 3956.9753f, 4677.3208f, 5122.2222f, 5539.0688f, 5993.0542f, + 334.7170f, 450.1582f, 747.3162f, 1560.2024f, 1808.2147f, 2006.5011f, 2415.2419f, + 2680.1956f, 3016.5549f, 3651.1340f, 3975.3625f, 4209.6563f, 4531.0396f, 5121.7212f, + 5585.2202f, 5962.3667f, 256.4101f, 495.5723f, 1341.4860f, 1805.1255f, 2201.8318f, + 2514.7769f, 2820.4092f, 3102.3867f, 3414.3872f, 3754.7742f, 4108.2378f, 4465.9258f, + 4857.4355f, 5216.2144f, 5592.3076f, 5951.9995f, 530.7974f, 1017.4255f, 1463.9575f, + 1858.6631f, 2360.1265f, 2770.3811f, 3106.0894f, 3379.1919f, 3647.7175f, 3895.9026f, + 4188.8652f, 4522.8984f, 4893.7954f, 5241.4312f, 5623.8994f, 5975.3608f, 597.1553f, + 1198.0758f, 1722.7361f, 2128.6658f, 2519.1504f, 2825.5122f, 3086.1943f, 3330.0283f, + 3608.2961f, 3906.9929f, 4241.8105f, 4603.1694f, 4972.8159f, 5308.1670f, 5651.1968f, + 5976.6704f, 699.1581f, 1293.3193f, 1637.3395f, 1912.7987f, 2163.3445f, 2425.7944f, + 2704.0396f, 3006.5984f, 3358.2126f, 3746.1548f, 4125.0762f, 4489.7485f, 4854.0088f, + 5188.5146f, 5558.2056f, 5913.3164f, 489.0107f, 921.4806f, 1329.8511f, 1644.8383f, + 2013.6794f, 2365.2683f, 2746.1553f, 3085.6912f, 3457.0234f, 3825.2183f, 4203.4224f, + 4575.9331f, 4950.6606f, 5298.7559f, 5659.8618f, 5997.0015f, 230.3653f, 389.8415f, + 938.1970f, 1294.3594f, 1768.8275f, 2189.1001f, 2597.3755f, 2985.8518f, 3323.6023f, + 3705.8533f, 4065.5361f, 4446.4224f, 4818.4502f, 5185.9634f, 5583.2168f, 5954.2573f, + 283.9404f, 400.2146f, 630.6198f, 1491.5646f, 2295.1375f, 2496.3457f, 2726.5803f, + 2971.1951f, 3207.2317f, 3634.5439f, 4178.0376f, 4423.5537f, 4836.2109f, 5172.1821f, + 5464.0454f, 5777.5801f, 242.6232f, 351.1541f, 807.9852f, 1621.9950f, 2043.8676f, + 2532.5122f, 2860.5505f, 3200.3403f, 3499.8274f, 3760.3772f, 4068.9617f, 4410.7339f, + 4778.8413f, 5153.0142f, 5553.1997f, 5932.5996f, 227.3320f, 323.2667f, 752.3189f, + 1572.3750f, 1930.6083f, 2355.0117f, 2717.6223f, 2968.3215f, 3233.4026f, 3551.9622f, + 3918.5608f, 4346.0190f, 4778.6880f, 5159.6172f, 5568.5566f, 5980.8086f, 307.9120f, + 439.7297f, 660.0276f, 1243.3854f, 1532.3577f, 1796.3936f, 2437.3232f, 2691.4072f, + 3030.3025f, 3524.1379f, 3771.7576f, 4083.2375f, 4601.1567f, 4963.4697f, 5434.8530f, + 5942.8315f}; + +const FLOAT32 iusace_wlsf_factor_table[4] = {60.0f, 65.0f, 64.0f, 63.0f}; diff --git a/encoder/iusace_block_switch.c b/encoder/iusace_block_switch.c new file mode 100644 index 0000000..44e44ea --- /dev/null +++ b/encoder/iusace_block_switch.c @@ -0,0 +1,282 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include "iusace_type_def.h" +#include "ixheaace_mps_common_define.h" +#include "iusace_cnst.h" +#include "iusace_block_switch_const.h" +#include "iusace_block_switch_struct_def.h" +#include "iusace_rom.h" + +static FLOAT32 iusace_fmult(FLOAT32 a, FLOAT32 b) { return (a * b); } + +static FLOAT32 iusace_fadd(FLOAT32 a, FLOAT32 b) { return (a + b); } + +VOID iusace_init_block_switching(ia_block_switch_ctrl *pstr_blk_switch_ctrl, + const WORD32 bit_rate, const WORD32 num_chans) { + WORD32 i, w; + + if ((num_chans == 1 && bit_rate > 24000) || (num_chans > 1 && bit_rate / num_chans > 16000)) { + pstr_blk_switch_ctrl->inv_attack_ratio = INV_ATTACK_RATIO_HIGH_BR; + } else { + pstr_blk_switch_ctrl->inv_attack_ratio = INV_ATTACK_RATIO_LOW_BR; + } + + for (i = 0; i < BLK_SWITCH_FILT_LEN; i++) { + pstr_blk_switch_ctrl->iir_states[i] = 0; + } + + /* Clear Filtered Window Energies */ + for (w = 0; w < MAX_SHORT_WINDOWS; w++) { + pstr_blk_switch_ctrl->win_energy_filt[0][w] = 0; + pstr_blk_switch_ctrl->win_energy_filt[1][w] = 0; + pstr_blk_switch_ctrl->win_energy[0][w] = 0; + pstr_blk_switch_ctrl->win_energy[1][w] = 0; + } + pstr_blk_switch_ctrl->acc_win_energy = 0; + + pstr_blk_switch_ctrl->window_seq = ONLY_LONG_SEQUENCE; + pstr_blk_switch_ctrl->next_win_seq = ONLY_LONG_SEQUENCE; + + pstr_blk_switch_ctrl->attack = 0; + pstr_blk_switch_ctrl->lastattack = 0; + pstr_blk_switch_ctrl->attack_idx = 0; + pstr_blk_switch_ctrl->last_attack_idx = 0; + + return; +} + +static FLOAT32 iusace_srch_max_with_idx(const FLOAT32 *ptr_in, WORD32 *index) { + FLOAT32 max; + WORD32 i, idx; + + max = 0; + idx = 0; + + for (i = 0; i < MAX_SHORT_WINDOWS; i++) { + if (ptr_in[i + 1] > max) { + max = ptr_in[i + 1]; + idx = i; + } + } + *index = idx; + + return max; +} + +static VOID iusace_blk_switch_iir_filt(const FLOAT32 *ptr_in, const FLOAT32 *ptr_iir_coeff, + const WORD32 w, FLOAT32 *ptr_iir_states, + FLOAT32 *energy_accu, WORD32 block_len) { + FLOAT32 accu1; + + WORD32 i; + + FLOAT32 accu_unfilt = 0.0f; + FLOAT32 accu_filt = 0.0f; + FLOAT32 accu2, temp2, temp1; + + FLOAT32 state0 = ptr_iir_states[0]; + FLOAT32 state1 = ptr_iir_states[1]; + + FLOAT32 coeff0 = ptr_iir_coeff[0]; + FLOAT32 coeff1 = ptr_iir_coeff[1]; + + const FLOAT32 *p_time_signal = &ptr_in[(block_len * w)]; + + for (i = 0; i < block_len; i++) { + accu2 = iusace_fmult(state0, coeff1); + accu1 = iusace_fmult(state1, coeff0); + accu1 += accu2; + + state0 = p_time_signal[i]; + state1 = iusace_fmult(state0, coeff1); + state1 = (state1 - accu1); + + temp1 = iusace_fmult(state0, state0); + temp2 = iusace_fmult(state1, state1); + + accu_unfilt = iusace_fadd(accu_unfilt, temp1); + accu_filt = iusace_fadd(accu_filt, temp2); + } + + energy_accu[0] = accu_unfilt; + energy_accu[1] = accu_filt; + + ptr_iir_states[0] = state0; + ptr_iir_states[1] = state1; + + return; +} + +static VOID iusace_calc_window_energy(ia_block_switch_ctrl *ptr_blk_switch_ctrl, + const FLOAT32 *ptr_in, FLOAT32 *max, WORD32 ccfl) { + WORD32 w; + + FLOAT32 energy_accu[2]; + *max = 0.0f; + + for (w = 0; w < MAX_SHORT_WINDOWS; w++) { + // block length for calculating energy is corecoder frame length / MAX_SHORT_WINDOWS + iusace_blk_switch_iir_filt(ptr_in, iusace_iir_hipass_coeffs, w, + ptr_blk_switch_ctrl->iir_states, &energy_accu[0], ccfl >> 3); + + ptr_blk_switch_ctrl->win_energy[1][w] = energy_accu[0]; + ptr_blk_switch_ctrl->win_energy_filt[1][w] = energy_accu[1]; + + if (ptr_blk_switch_ctrl->win_energy_filt[1][w] > *max) + *max = ptr_blk_switch_ctrl->win_energy_filt[1][w]; + } + return; +} + +VOID iusace_block_switching(ia_block_switch_ctrl *ptr_blk_switch_ctrl, const FLOAT32 *ptr_in, + WORD32 ccfl) { + WORD32 i; + + FLOAT32 temp1, temp2; + FLOAT32 max; + FLOAT32 energy, energy_max; + + for (i = 0; i < MAX_SHORT_WINDOWS; i++) { + ptr_blk_switch_ctrl->group_len[i] = 0; + } + + ptr_blk_switch_ctrl->max_win_energy = + iusace_srch_max_with_idx(&ptr_blk_switch_ctrl->win_energy[0][MAX_SHORT_WINDOWS - 1], + &ptr_blk_switch_ctrl->attack_idx); + + ptr_blk_switch_ctrl->attack_idx = ptr_blk_switch_ctrl->last_attack_idx; + ptr_blk_switch_ctrl->tot_grps_cnt = MAXIMUM_NO_OF_GROUPS; + + for (i = 0; i < MAXIMUM_NO_OF_GROUPS; i++) { + ptr_blk_switch_ctrl->group_len[i] = + iusace_suggested_grouping_table[ptr_blk_switch_ctrl->attack_idx][i]; + } + + for (i = 0; i < MAX_SHORT_WINDOWS; i++) { + ptr_blk_switch_ctrl->win_energy[0][i] = ptr_blk_switch_ctrl->win_energy[1][i]; + ptr_blk_switch_ctrl->win_energy_filt[0][i] = ptr_blk_switch_ctrl->win_energy_filt[1][i]; + } + + iusace_calc_window_energy(ptr_blk_switch_ctrl, ptr_in, &max, ccfl); + + ptr_blk_switch_ctrl->attack = FALSE; + + energy_max = 0.0f; + + energy = ptr_blk_switch_ctrl->win_energy_filt[0][MAX_SHORT_WINDOWS - 1]; + + for (i = 0; i < MAX_SHORT_WINDOWS; i++) { + temp1 = iusace_fmult(ONE_MINUS_ACC_WINDOW_NRG_FAC, ptr_blk_switch_ctrl->acc_win_energy); + temp2 = iusace_fmult(ACC_WINDOW_NRG_FAC, energy); + ptr_blk_switch_ctrl->acc_win_energy = iusace_fadd(temp1, temp2); + + temp1 = iusace_fmult(ptr_blk_switch_ctrl->win_energy_filt[1][i], + ptr_blk_switch_ctrl->inv_attack_ratio); + if (temp1 > ptr_blk_switch_ctrl->acc_win_energy) { + ptr_blk_switch_ctrl->attack = TRUE; + ptr_blk_switch_ctrl->last_attack_idx = i; + } + + energy = ptr_blk_switch_ctrl->win_energy_filt[1][i]; + if (energy_max < energy) energy_max = energy; + } + + if (ccfl == LEN_SUPERFRAME_768) { + energy_max = (energy_max * 4) / 3.0f; + } + if (energy_max < USAC_MIN_ATTACK_NRG) { + ptr_blk_switch_ctrl->attack = FALSE; + } + + if ((!ptr_blk_switch_ctrl->attack) && (ptr_blk_switch_ctrl->lastattack)) { + if (ptr_blk_switch_ctrl->attack_idx == MAX_SHORT_WINDOWS - 1) { + ptr_blk_switch_ctrl->attack = TRUE; + } + ptr_blk_switch_ctrl->lastattack = FALSE; + } else { + ptr_blk_switch_ctrl->lastattack = ptr_blk_switch_ctrl->attack; + } + ptr_blk_switch_ctrl->window_seq = ptr_blk_switch_ctrl->next_win_seq; + + if (ptr_blk_switch_ctrl->attack) { + ptr_blk_switch_ctrl->next_win_seq = EIGHT_SHORT_SEQUENCE; + } else { + ptr_blk_switch_ctrl->next_win_seq = ONLY_LONG_SEQUENCE; + } + if (ptr_blk_switch_ctrl->next_win_seq == EIGHT_SHORT_SEQUENCE) { + if (ptr_blk_switch_ctrl->window_seq == ONLY_LONG_SEQUENCE) { + ptr_blk_switch_ctrl->window_seq = LONG_START_SEQUENCE; + } + + if (ptr_blk_switch_ctrl->window_seq == LONG_STOP_SEQUENCE) { + ptr_blk_switch_ctrl->window_seq = EIGHT_SHORT_SEQUENCE; + ptr_blk_switch_ctrl->tot_grps_cnt = 3; + ptr_blk_switch_ctrl->group_len[0] = 3; + ptr_blk_switch_ctrl->group_len[1] = 3; + ptr_blk_switch_ctrl->group_len[2] = 2; + } + } + + if (ptr_blk_switch_ctrl->next_win_seq == ONLY_LONG_SEQUENCE) { + if (ptr_blk_switch_ctrl->window_seq == EIGHT_SHORT_SEQUENCE) { + ptr_blk_switch_ctrl->next_win_seq = LONG_STOP_SEQUENCE; + } + } + return; +} + +VOID iusace_sync_block_switching(ia_block_switch_ctrl *ptr_blk_switch_left_ctrl, + ia_block_switch_ctrl *ptr_blk_switch_right_ctrl) { + WORD32 i; + WORD32 patch_type = ONLY_LONG_SEQUENCE; + + patch_type = iusace_synchronized_block_types[patch_type][ptr_blk_switch_left_ctrl->window_seq]; + patch_type = iusace_synchronized_block_types[patch_type][ptr_blk_switch_right_ctrl->window_seq]; + + ptr_blk_switch_left_ctrl->window_seq = patch_type; + ptr_blk_switch_right_ctrl->window_seq = patch_type; + + if (patch_type != EIGHT_SHORT_SEQUENCE) { /* tns_data_long Blocks */ + ptr_blk_switch_left_ctrl->tot_grps_cnt = 1; + ptr_blk_switch_right_ctrl->tot_grps_cnt = 1; + ptr_blk_switch_left_ctrl->group_len[0] = 1; + ptr_blk_switch_right_ctrl->group_len[0] = 1; + + for (i = 1; i < MAX_SHORT_WINDOWS; i++) { + ptr_blk_switch_left_ctrl->group_len[i] = 0; + ptr_blk_switch_right_ctrl->group_len[i] = 0; + } + } else { /* tns_data_short Blocks */ + if (ptr_blk_switch_left_ctrl->max_win_energy > ptr_blk_switch_right_ctrl->max_win_energy) { + ptr_blk_switch_right_ctrl->tot_grps_cnt = ptr_blk_switch_left_ctrl->tot_grps_cnt; + for (i = 0; i < ptr_blk_switch_right_ctrl->tot_grps_cnt; i++) { + ptr_blk_switch_right_ctrl->group_len[i] = ptr_blk_switch_left_ctrl->group_len[i]; + } + } else { + ptr_blk_switch_left_ctrl->tot_grps_cnt = ptr_blk_switch_right_ctrl->tot_grps_cnt; + for (i = 0; i < ptr_blk_switch_left_ctrl->tot_grps_cnt; i++) { + ptr_blk_switch_left_ctrl->group_len[i] = ptr_blk_switch_right_ctrl->group_len[i]; + } + } + } + + return; +} diff --git a/encoder/iusace_block_switch.h b/encoder/iusace_block_switch.h new file mode 100644 index 0000000..3244e9c --- /dev/null +++ b/encoder/iusace_block_switch.h @@ -0,0 +1,27 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +VOID iusace_init_block_switching(ia_block_switch_ctrl *pstr_blk_switch_ctrl, + const WORD32 bit_rate, const WORD32 num_chans); +VOID iusace_block_switching(ia_block_switch_ctrl *ptr_blk_switch_ctrl, const FLOAT32 *ptr_in, + WORD32 ccfl); +VOID iusace_sync_block_switching(ia_block_switch_ctrl *ptr_blk_switch_left_ctrl, + ia_block_switch_ctrl *ptr_blk_switch_right_ctrl); diff --git a/encoder/iusace_block_switch_const.h b/encoder/iusace_block_switch_const.h new file mode 100644 index 0000000..bb843ea --- /dev/null +++ b/encoder/iusace_block_switch_const.h @@ -0,0 +1,45 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +#define TRANS_FAC 8 + +#define BLK_SWITCH_WIN 8 +#define BLK_SWITCH_FILT_LEN 2 + +/* Block types */ +#define LONG_WINDOW 0 +#define START_WINDOW 1 +#define SHORT_WINDOW 2 +#define STOP_WINDOW 3 + +/* Window shapes */ +#define SINE_WINDOW 0 +#define KBD_WINDOW 1 + +#define MAXIMUM_NO_OF_GROUPS 4 + +#define ACC_WINDOW_NRG_FAC 0.3f +#define ONE_MINUS_ACC_WINDOW_NRG_FAC 0.7f +#define INV_ATTACK_RATIO_HIGH_BR 0.1f +#define INV_ATTACK_RATIO_LOW_BR 0.056f +#define USAC_MIN_ATTACK_NRG 1e+6 +#define CLIP_ENERGY_VALUE_LONG (1.0e9f) +#define CLIP_ENERGY_VALUE_SHORT (15625000.0f) diff --git a/encoder/iusace_block_switch_struct_def.h b/encoder/iusace_block_switch_struct_def.h new file mode 100644 index 0000000..085fd96 --- /dev/null +++ b/encoder/iusace_block_switch_struct_def.h @@ -0,0 +1,39 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +typedef struct { + FLOAT32 inv_attack_ratio; + WORD32 window_seq; + WORD32 next_win_seq; + WORD32 attack; + WORD32 lastattack; + WORD32 attack_idx; + WORD32 last_attack_idx; + + WORD32 tot_grps_cnt; + WORD32 group_len[TRANS_FAC]; + + FLOAT32 win_energy[2][BLK_SWITCH_WIN]; + FLOAT32 win_energy_filt[2][BLK_SWITCH_WIN]; + FLOAT32 iir_states[BLK_SWITCH_FILT_LEN]; + FLOAT32 max_win_energy; + FLOAT32 acc_win_energy; +} ia_block_switch_ctrl; diff --git a/encoder/iusace_cnst.h b/encoder/iusace_cnst.h index 6e82517..e439f5a 100644 --- a/encoder/iusace_cnst.h +++ b/encoder/iusace_cnst.h @@ -200,3 +200,4 @@ #define USACE_MAX_SCR_SIZE (733836) #define USACE_SCR_STACK (10 * 1024) +#define MAX_USAC_ESBR_BITRATE (96000) diff --git a/encoder/iusace_config.h b/encoder/iusace_config.h index 95b1d46..c1aeedd 100644 --- a/encoder/iusace_config.h +++ b/encoder/iusace_config.h @@ -130,3 +130,206 @@ typedef struct { VOID *ptr_drc_scratch_buf; VOID *ptr_stack_mem; } iusace_scratch_mem; + +#define USAC_MAX_ELEMENTS (32) +#define USAC_MAX_CONFIG_EXTENSIONS (16) + +#define ID_USAC_SCE 0 +#define ID_USAC_CPE 1 +#define ID_USAC_EXT 3 + +#define AOT_SBR (5) +#define AOT_USAC (42) + +#define ID_EXT_ELE_FILL 0 +#define ID_EXT_ELE_UNI_DRC 4 + +#define ID_CONFIG_EXT_FILL 0 +#define ID_CONFIG_EXT_DOWNMIX (1) +#define ID_CONFIG_EXT_LOUDNESS_INFO (2) +#define NUM_COEFF (1024) + +typedef enum { + + USAC_ELEMENT_TYPE_INVALID = -1, + USAC_ELEMENT_TYPE_SCE = 0, + USAC_ELEMENT_TYPE_CPE = 1, + USAC_ELEMENT_TYPE_EXT = 3 + +} ia_usac_ele_type; + +typedef struct { + UWORD32 harmonic_sbr; + UWORD32 bs_inter_tes; + UWORD32 bs_pvc; + UWORD32 dflt_start_freq; + UWORD32 dflt_stop_freq; + UWORD32 dflt_header_extra1; + UWORD32 dflt_header_extra2; + UWORD32 dflt_freq_scale; + UWORD32 dflt_alter_scale; + UWORD32 dflt_noise_bands; + UWORD32 dflt_limiter_bands; + UWORD32 dflt_limiter_gains; + UWORD32 dflt_interpol_freq; + UWORD32 dflt_smoothing_mode; +} ia_usac_enc_sbr_config_struct; + +typedef struct { + WORD32 bs_tree_config; + WORD32 bs_freq_res; + WORD32 bs_fixed_gain_dmx; + WORD32 bs_temp_shape_config; + WORD32 bs_decorr_config; + WORD32 bs_residual_coding; + WORD32 bs_residual_bands; + WORD32 bs_low_rate_mode; + WORD32 bs_phase_coding; + WORD32 bs_quant_coarse_xxx; + WORD32 bs_ott_bands_phase; + WORD32 bs_ott_bands_phase_present; + WORD32 bs_pseudo_lr; + WORD32 bs_env_quant_mode; + WORD32 bs_high_rate_mode; +} ia_usac_enc_mps_config_struct; + +typedef struct { + UWORD32 usac_ext_ele_type; + UWORD32 usac_ext_ele_cfg_len; + UWORD32 usac_ext_ele_dflt_len_present; + UWORD32 usac_ext_ele_dflt_len; + UWORD32 usac_ext_ele_payload_present; + UWORD32 stereo_config_index; + UWORD32 tw_mdct; + UWORD32 noise_filling; + UWORD8 usac_ext_ele_cfg_payload[6144 / 8]; + ia_usac_enc_sbr_config_struct str_usac_sbr_config; + ia_usac_enc_mps_config_struct str_usac_mps212_config; + UWORD8 *drc_config_data; +} ia_usac_enc_element_config_struct; + +typedef struct { + UWORD32 num_elements; + UWORD32 num_ext_elements; + UWORD32 usac_element_type[USAC_MAX_ELEMENTS]; + UWORD32 usac_cfg_ext_present; + UWORD32 num_config_extensions; + UWORD32 usac_config_ext_type[USAC_MAX_CONFIG_EXTENSIONS]; + UWORD32 usac_config_ext_len[USAC_MAX_CONFIG_EXTENSIONS]; + UWORD8 *usac_config_ext_buf[USAC_MAX_CONFIG_EXTENSIONS]; + UWORD8 usac_cfg_ext_info_buf[USAC_MAX_CONFIG_EXTENSIONS][6144 / 8]; + WORD32 num_out_channels; + WORD32 num_signal_grp; + WORD32 output_channel_pos[BS_MAX_NUM_OUT_CHANNELS]; + WORD32 ccfl; + ia_usac_enc_element_config_struct str_usac_element_config[USAC_MAX_ELEMENTS]; +} ia_usac_config_struct; + +typedef struct { + WORD32 aac_allow_scalefacs; + WORD32 aac_scale_facs; + WORD32 bit_rate; + WORD32 basic_bitrate; + WORD32 bw_limit[USAC_MAX_ELEMENTS]; + WORD32 ccfl; + WORD32 ccfl_idx; + WORD32 channels; + WORD32 codec_mode; + WORD32 flag_noiseFilling; + WORD32 iframes_interval; + UWORD32 num_elements; + UWORD32 num_ext_elements; + + WORD32 sample_rate; + WORD32 native_sample_rate; + WORD32 core_sample_rate; + + WORD32 tns_select; + WORD32 ui_pcm_wd_sz; + WORD32 use_fill_element; + WORD32 window_shape_prev[MAX_TIME_CHANNELS]; + WORD32 window_shape_prev_copy[MAX_TIME_CHANNELS]; + WORD32 window_sequence[MAX_TIME_CHANNELS]; + WORD32 window_sequence_prev[MAX_TIME_CHANNELS]; + WORD32 window_sequence_prev_copy[MAX_TIME_CHANNELS]; + WORD32 cmplx_pred_flag; + WORD32 wshape_flag; + WORD32 delay_total; + WORD32 in_frame_length; + // eSBR Parameters + WORD32 sbr_enable; + WORD32 sbr_ratio_idx; + WORD32 up_sample_ratio; + WORD32 sbr_pvc_active; + WORD32 sbr_harmonic; + WORD32 hq_esbr; + WORD32 sbr_inter_tes_active; + // MPS Parameters + WORD32 usac212enable; + ia_sfb_params_struct str_sfb_prms; + // DRC Params + FLAG use_drc_element; + WORD32 drc_frame_size; + ia_drc_input_config str_drc_cfg; +} ia_usac_encoder_config_struct; + +typedef struct { + WORD32 mode; + WORD32 num_bits; + FLOAT32 lpc_coeffs_quant[2 * (ORDER + 1)]; + FLOAT32 lpc_coeffs[2 * (ORDER + 1)]; + FLOAT32 synth[ORDER + 128]; + FLOAT32 wsynth[1 + 128]; + FLOAT32 acelp_exc[2 * LEN_FRAME]; + WORD32 avq_params[FAC_LENGTH]; + FLOAT32 tcx_mem[128]; + FLOAT32 tcx_quant[1 + (2 * 128)]; + FLOAT32 tcx_fac; + FLOAT32 mem_wsyn; +} ia_usac_lpd_state_struct; + +typedef struct { + WORD32 len_frame; + WORD32 len_subfrm; + WORD32 num_subfrm; + WORD16 acelp_core_mode; + WORD32 fscale; + FLOAT32 mem_lp_decim2[3]; + WORD32 decim_frac; + FLOAT32 mem_sig_in[4]; + FLOAT32 mem_preemph; + FLOAT32 old_speech_pe[L_OLD_SPEECH_HIGH_RATE + LEN_LPC0]; + FLOAT32 weighted_sig[128]; + ia_usac_lpd_state_struct lpd_state; + FLOAT32 prev_wsp[MAX_PITCH / OPL_DECIM]; + FLOAT32 prev_exc[MAX_PITCH + LEN_INTERPOL]; + FLOAT32 prev_wsyn_mem; + FLOAT32 prev_wsp_mem; + FLOAT32 prev_xnq_mem; + WORD32 prev_ovlp_size; + FLOAT32 isf_old[ORDER]; + FLOAT32 isp_old[ORDER]; + FLOAT32 isp_old_q[ORDER]; + FLOAT32 mem_wsp; + FLOAT32 ada_w; + FLOAT32 ol_gain; + WORD16 ol_wght_flg; + WORD32 prev_ol_lags[5]; + WORD32 prev_pitch_med; + FLOAT32 prev_hp_wsp[LEN_SUPERFRAME / OPL_DECIM + (MAX_PITCH / OPL_DECIM)]; + FLOAT32 hp_ol_ltp_mem[3 * 2 + 1]; + const FLOAT32 *lp_analysis_window; + FLOAT32 xn_buffer[128]; + WORD32 c_prev[(NUM_COEFF / 2) + 4]; + WORD32 c_pres[(NUM_COEFF / 2) + 4]; + WORD32 arith_reset_flag; + WORD16 prev_mode; + WORD32 num_bits_per_supfrm; + FLOAT32 fd_synth[2 * LEN_FRAME + 1 + ORDER]; + FLOAT32 fd_orig[2 * LEN_FRAME + 1 + ORDER]; + WORD32 low_pass_line; + WORD32 last_was_short; + WORD32 next_is_short; + FLOAT32 gain_tcx; + WORD32 max_sfb_short; +} ia_usac_td_encoder_struct; diff --git a/encoder/iusace_enc_fac.c b/encoder/iusace_enc_fac.c new file mode 100644 index 0000000..68cfda8 --- /dev/null +++ b/encoder/iusace_enc_fac.c @@ -0,0 +1,534 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include "ixheaac_type_def.h" +#include "ixheaace_adjust_threshold_data.h" +#include "iusace_bitbuffer.h" + +/* DRC */ +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" +#include "impd_drc_uni_drc_eq.h" +#include "impd_drc_uni_drc_filter_bank.h" +#include "impd_drc_gain_enc.h" +#include "impd_drc_struct_def.h" + +#include "iusace_cnst.h" +#include "iusace_tns_usac.h" +#include "iusace_psy_mod.h" +#include "iusace_config.h" +#include "iusace_arith_enc.h" +#include "iusace_block_switch_const.h" +#include "iusace_block_switch_struct_def.h" +#include "iusace_fd_qc_util.h" +#include "iusace_fd_quant.h" +#include "iusace_ms.h" +#include "iusace_signal_classifier.h" +#include "ixheaace_sbr_header.h" +#include "ixheaace_config.h" +#include "ixheaace_asc_write.h" +#include "iusace_main.h" +#include "iusace_write_bitstream.h" +#include "iusace_func_prototypes.h" +#include "iusace_avq_enc.h" +#include "iusace_lpd_rom.h" + +static WORD32 iusace_unary_code(WORD32 idx, WORD16 *ptr_bit_buf) { + WORD32 num_bits; + + num_bits = 1; + + idx -= 1; + while (idx-- > 0) { + *ptr_bit_buf++ = 1; + num_bits++; + } + + *ptr_bit_buf = 0; + + return (num_bits); +} + +static VOID iusace_get_nk_mode(WORD32 mode_lpc, ia_bit_buf_struct *pstr_it_bit_buff, + WORD32 *nk_mode, WORD32 lpc_set) { + switch (lpc_set) { + case 4: + break; + case 0: + case 2: + *nk_mode = 3; + iusace_write_bits_buf(pstr_it_bit_buff, mode_lpc, 1); + break; + case 1: + *nk_mode = mode_lpc; + if (mode_lpc == 2) { + iusace_write_bits_buf(pstr_it_bit_buff, 0, 1); + } else if (mode_lpc == 1) { + iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); + iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); + } else if (mode_lpc == 0) { + iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); + iusace_write_bits_buf(pstr_it_bit_buff, 0, 1); + } + break; + case 3: + if (mode_lpc == 0) { + *nk_mode = 0; + iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); + iusace_write_bits_buf(pstr_it_bit_buff, 0, 1); + } else if (mode_lpc == 1) { + *nk_mode = 1; + iusace_write_bits_buf(pstr_it_bit_buff, 0, 1); + } else if (mode_lpc == 2) { + *nk_mode = 2; + iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); + iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); + iusace_write_bits_buf(pstr_it_bit_buff, 0, 1); + } else { + *nk_mode = 2; + iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); + iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); + iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); + } + break; + } + return; +} + +static VOID iusace_write_qn_data(WORD32 *qn, ia_bit_buf_struct *pstr_it_bit_buff, WORD32 nk_mode, + WORD32 num_frames) { + WORD32 k, i; + switch (nk_mode) { + case 1: + for (k = 0; k < 2; k++) { + for (i = 0; i < qn[k] - 1; i++) { + iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); + } + iusace_write_bits_buf(pstr_it_bit_buff, 0, 1); + } + break; + case 0: + case 2: + case 3: + for (k = 0; k < 2; k++) { + WORD32 qn1 = qn[k] - 2; + if (qn1 < 0 || qn1 > 3) { + qn1 = 3; + } + iusace_write_bits_buf(pstr_it_bit_buff, qn1, 2); + } + if ((nk_mode == 2) && num_frames != 2) { + for (k = 0; k < 2; k++) { + if (qn[k] > 4) { + for (i = 0; i < qn[k] - 4; i++) { + iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); + } + iusace_write_bits_buf(pstr_it_bit_buff, 0, 1); + } + if (qn[k] == 0) { + iusace_write_bits_buf(pstr_it_bit_buff, 0, 1); + } + } + } else { + for (k = 0; k < 2; k++) { + if (qn[k] == 5) { + iusace_write_bits_buf(pstr_it_bit_buff, 0, 1); + } else if (qn[k] == 6) { + iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); + iusace_write_bits_buf(pstr_it_bit_buff, 0, 1); + } else if (qn[k] == 0) { + iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); + iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); + iusace_write_bits_buf(pstr_it_bit_buff, 0, 1); + } else { + WORD32 qn_ext = qn[k] - 4; + if (qn_ext > 0) { + for (i = 0; i < qn_ext; i++) { + iusace_write_bits_buf(pstr_it_bit_buff, 1, 1); + } + iusace_write_bits_buf(pstr_it_bit_buff, 0, 1); + } + } + } + } + break; + } + return; +} + +static VOID iusace_write_cb_indices(WORD32 *qn, WORD32 *ptr_params, WORD32 *idx, + ia_bit_buf_struct *pstr_it_bit_buff, WORD32 nk_mode, + WORD32 num_frames) { + WORD32 k; + WORD32 j = *idx; + + iusace_write_qn_data(qn, pstr_it_bit_buff, nk_mode, num_frames); + + for (k = 0; k < 2; k++) { + if (qn[k] > 0) { + WORD32 n, nk, i; + if (qn[k] > 4) { + nk = (qn[k] - 3) >> 1; + n = qn[k] - nk * 2; + } else { + nk = 0; + n = qn[k]; + } + + iusace_write_bits_buf(pstr_it_bit_buff, ptr_params[j++], (UWORD8)(4 * n)); + + for (i = 0; i < 8; i++) { + iusace_write_bits_buf(pstr_it_bit_buff, ptr_params[j++], (UWORD8)nk); + } + } + } + + *idx = j; + + return; +} + +static VOID iusace_write_lpc_data(ia_bit_buf_struct *pstr_it_bit_buff, WORD32 *param_lpc, + WORD32 first_lpd_flag, WORD32 *mod, WORD32 num_frames) { + WORD32 nk_mode = 0; + WORD32 j = 0, k; + WORD32 mode_lpc = 0; + WORD32 qn[2] = {0}; + + iusace_get_nk_mode(mode_lpc, pstr_it_bit_buff, &nk_mode, 4); + + iusace_write_bits_buf(pstr_it_bit_buff, param_lpc[j++], 8); + + for (k = 0; k < 2; k++) { + qn[k] = param_lpc[j++]; + } + + iusace_write_cb_indices(qn, param_lpc, &j, pstr_it_bit_buff, nk_mode, num_frames); + + if (first_lpd_flag) { + mode_lpc = param_lpc[j++]; + iusace_get_nk_mode(mode_lpc, pstr_it_bit_buff, &nk_mode, 0); + + if (mode_lpc == 0) { + iusace_write_bits_buf(pstr_it_bit_buff, param_lpc[j++], 8); + } + + for (k = 0; k < 2; k++) { + qn[k] = param_lpc[j++]; + } + + iusace_write_cb_indices(qn, param_lpc, &j, pstr_it_bit_buff, nk_mode, num_frames); + } + + mode_lpc = param_lpc[j++]; + + if (num_frames == 4 && mod[0] < 3) { + iusace_get_nk_mode(mode_lpc, pstr_it_bit_buff, &nk_mode, 2); + + if (mode_lpc == 0) { + iusace_write_bits_buf(pstr_it_bit_buff, param_lpc[j++], 8); + } + + for (k = 0; k < 2; k++) { + qn[k] = param_lpc[j++]; + } + + iusace_write_cb_indices(qn, param_lpc, &j, pstr_it_bit_buff, nk_mode, num_frames); + } + mode_lpc = param_lpc[j++]; + if (mod[0] < 2) { + iusace_get_nk_mode(mode_lpc, pstr_it_bit_buff, &nk_mode, 1); + + if (mode_lpc != 1) { + if (mode_lpc == 0) { + iusace_write_bits_buf(pstr_it_bit_buff, param_lpc[j++], 8); + } + + for (k = 0; k < 2; k++) { + qn[k] = param_lpc[j++]; + } + + iusace_write_cb_indices(qn, param_lpc, &j, pstr_it_bit_buff, nk_mode, num_frames); + } + } else if (mode_lpc != 1) { + if (mode_lpc == 0) { + j++; + } + for (k = 0; k < 2; k++) { + qn[k] = param_lpc[j++]; + } + j += ((qn[0] > 0) ? 9 : 0) + ((qn[1] > 0) ? 9 : 0); + } + + mode_lpc = param_lpc[j++]; + if (num_frames != 2 && mod[2] < 2) { + iusace_get_nk_mode(mode_lpc, pstr_it_bit_buff, &nk_mode, 3); + if (mode_lpc == 0) { + iusace_write_bits_buf(pstr_it_bit_buff, param_lpc[j++], 8); + } + + for (k = 0; k < 2; k++) { + qn[k] = param_lpc[j++]; + } + iusace_write_cb_indices(qn, param_lpc, &j, pstr_it_bit_buff, nk_mode, num_frames); + } + return; +} + +VOID iusace_encode_fac_params(WORD32 *mod, WORD32 *n_param_tcx, ia_usac_data_struct *usac_data, + WORD32 const usac_independency_flag, + ia_bit_buf_struct *pstr_it_bit_buff, WORD32 ch_idx) { + WORD32 *total_nbbits = &usac_data->total_nbbits[ch_idx]; + ia_usac_td_encoder_struct *pstr_td = usac_data->td_encoder[ch_idx]; + WORD32 codec_mode = pstr_td->acelp_core_mode; + WORD16 *bit_buf = usac_data->td_serial_out[ch_idx]; + WORD32 is_bass_post_filter = 1; + WORD32 first_lpd_flag = (usac_data->core_mode_prev[ch_idx] == CORE_MODE_FD); + WORD32 *param_lpc = usac_data->param_buf + (NUM_FRAMES * MAX_NUM_TCX_PRM_PER_DIV); + WORD32 *param = usac_data->param_buf; + WORD32 j, k, n, sfr, lpd_mode, num_bits, sq_bits, *prm; + WORD16 first_tcx_flag = 1; + WORD32 nbits_fac, nb_bits_lpc; + WORD32 core_mode_last = (first_lpd_flag) ? 0 : 1; + WORD32 fac_data_present; + WORD32 num_frames = NUM_FRAMES; + WORD16 *ptr_bit_buf = bit_buf; + + pstr_td->num_bits_per_supfrm = 0; + *total_nbbits = 0; + + iusace_write_bits_buf(pstr_it_bit_buff, pstr_td->acelp_core_mode, 3); + + if (mod[0] == 3) { + lpd_mode = 25; + } else if ((mod[0] == 2) && (mod[2] == 2)) { + lpd_mode = 24; + } else { + if (mod[0] == 2) { + lpd_mode = 16 + mod[2] + 2 * mod[3]; + } else if (mod[2] == 2) { + lpd_mode = 20 + mod[0] + 2 * mod[1]; + } else { + lpd_mode = mod[0] + 2 * mod[1] + 4 * mod[2] + 8 * mod[3]; + } + } + iusace_write_bits_buf(pstr_it_bit_buff, lpd_mode, 5); + pstr_td->num_bits_per_supfrm = 5; + *total_nbbits += 5; + + iusace_write_bits_buf(pstr_it_bit_buff, is_bass_post_filter, 1); + *total_nbbits += 1; + + iusace_write_bits_buf(pstr_it_bit_buff, core_mode_last, 1); + *total_nbbits += 1; + + if (((mod[0] == 0) && (mod[-1] != 0)) || ((mod[0] > 0) && (mod[-1] == 0))) { + fac_data_present = 1; + } else { + fac_data_present = 0; + } + + iusace_write_bits_buf(pstr_it_bit_buff, fac_data_present, 1); + *total_nbbits += 1; + + num_bits = (iusace_acelp_core_numbits_1024[codec_mode] / 4) - 2; + + k = 0; + while (k < num_frames) { + lpd_mode = mod[k]; + prm = param + (k * MAX_NUM_TCX_PRM_PER_DIV); + j = 0; + + if (((mod[k - 1] == 0) && (mod[k] > 0)) || ((mod[k - 1] > 0) && (mod[k] == 0))) { + nbits_fac = iusace_fd_encode_fac(&prm[j], ptr_bit_buf, (pstr_td->len_subfrm) / 2); + j += (pstr_td->len_subfrm) / 2; + *total_nbbits += nbits_fac; + for (WORD32 i = 0; i < nbits_fac; i++) { + iusace_write_bits_buf(pstr_it_bit_buff, ptr_bit_buf[i], 1); + } + } + + if (lpd_mode == 0) { + iusace_write_bits_buf(pstr_it_bit_buff, prm[j++], 2); + + for (sfr = 0; sfr < (pstr_td->num_subfrm); sfr++) { + n = 6; + if ((sfr == 0) || (((pstr_td->len_subfrm) == 256) && (sfr == 2))) n = 9; + iusace_write_bits_buf(pstr_it_bit_buff, prm[j], (UWORD8)n); + j++; + iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 1); + j++; + if (codec_mode == ACELP_CORE_MODE_9k6) { + iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 5); + j++; + iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 5); + j++; + iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 5); + j++; + iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 5); + j++; + } else if (codec_mode == ACELP_CORE_MODE_11k2) { + iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 9); + j++; + iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 9); + j++; + iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 5); + j++; + iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 5); + j++; + } else if (codec_mode == ACELP_CORE_MODE_12k8) { + iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 9); + j++; + iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 9); + j++; + iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 9); + j++; + iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 9); + j++; + } else if (codec_mode == ACELP_CORE_MODE_14k4) { + iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 13); + j++; + iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 13); + j++; + iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 9); + j++; + iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 9); + j++; + } else if (codec_mode == ACELP_CORE_MODE_16k) { + iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 13); + j++; + iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 13); + j++; + iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 13); + j++; + iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 13); + j++; + } else if (codec_mode == ACELP_CORE_MODE_18k4) { + iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 2); + j++; + iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 2); + j++; + iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 2); + j++; + iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 2); + j++; + iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 14); + j++; + iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 14); + j++; + iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 14); + j++; + iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 14); + j++; + } + iusace_write_bits_buf(pstr_it_bit_buff, prm[j], 7); + j++; + } + *total_nbbits += (num_bits - NBITS_LPC); + pstr_td->num_bits_per_supfrm += (num_bits - NBITS_LPC); + k++; + } else { + iusace_write_bits_buf(pstr_it_bit_buff, prm[j++], 3); + *total_nbbits += 3; + pstr_td->num_bits_per_supfrm += 3; + iusace_write_bits_buf(pstr_it_bit_buff, prm[j++], 7); + *total_nbbits += 7; + pstr_td->num_bits_per_supfrm += 7; + + if (first_tcx_flag) { + first_tcx_flag = 0; + if (usac_independency_flag) { + pstr_td->arith_reset_flag = 1; + memset(pstr_td->c_pres, 0, 516 * sizeof(WORD32)); + memset(pstr_td->c_prev, 0, 516 * sizeof(WORD32)); + } else { + if (pstr_td->arith_reset_flag) { + memset(pstr_td->c_pres, 0, 516 * sizeof(WORD32)); + memset(pstr_td->c_prev, 0, 516 * sizeof(WORD32)); + } + iusace_write_bits_buf(pstr_it_bit_buff, pstr_td->arith_reset_flag, 1); + *total_nbbits += 1; + pstr_td->num_bits_per_supfrm += 1; + } + } + + sq_bits = iusace_tcx_coding(pstr_it_bit_buff, n_param_tcx[k], pstr_td->len_frame, prm + j, + pstr_td->c_pres, pstr_td->c_prev); + + *total_nbbits += sq_bits; + pstr_td->num_bits_per_supfrm += sq_bits; + + k += (1 << (lpd_mode - 1)); + } + } + + nb_bits_lpc = pstr_it_bit_buff->cnt_bits; + + iusace_write_lpc_data(pstr_it_bit_buff, param_lpc, first_lpd_flag, mod, num_frames); + + nb_bits_lpc = pstr_it_bit_buff->cnt_bits - nb_bits_lpc; + *total_nbbits += nb_bits_lpc; + pstr_td->num_bits_per_supfrm += nb_bits_lpc; + + if ((core_mode_last == 0) && (fac_data_present == 1)) { + WORD32 short_fac_flag = (mod[-1] == -2) ? 1 : 0; + iusace_write_bits_buf(pstr_it_bit_buff, short_fac_flag, 1); + *total_nbbits += 1; + } + + return; +} + +WORD32 iusace_fd_encode_fac(WORD32 *prm, WORD16 *ptr_bit_buf, WORD32 fac_length) { + WORD32 i, j, n, nb, qn, kv[8], nk, fac_bits; + WORD32 I; + + fac_bits = 0; + + for (i = 0; i < fac_length; i += 8) { + iusace_apply_voronoi_ext(&prm[i], &qn, &I, kv); + + nb = iusace_unary_code(qn, ptr_bit_buf); + ptr_bit_buf += nb; + + fac_bits += nb; + + nk = 0; + n = qn; + if (qn > 4) { + nk = (qn - 3) >> 1; + n = qn - nk * 2; + } + + iusace_write_bits2buf(I, 4 * n, ptr_bit_buf); + ptr_bit_buf += 4 * n; + for (j = 0; j < 8; j++) { + iusace_write_bits2buf(kv[j], nk, ptr_bit_buf); + ptr_bit_buf += nk; + } + + fac_bits += 4 * qn; + } + + return fac_bits; +} diff --git a/encoder/iusace_enc_main.c b/encoder/iusace_enc_main.c new file mode 100644 index 0000000..69f507e --- /dev/null +++ b/encoder/iusace_enc_main.c @@ -0,0 +1,1333 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include +#include + +#include "ixheaac_error_standards.h" +#include "iusace_type_def.h" +#include "ixheaace_adjust_threshold_data.h" +#include "iusace_bitbuffer.h" +#include "ixheaace_bitbuffer.h" +#include "ixheaace_mps_common_define.h" + +/* DRC */ +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" +#include "impd_drc_uni_drc_eq.h" +#include "impd_drc_uni_drc_filter_bank.h" +#include "impd_drc_gain_enc.h" +#include "impd_drc_struct_def.h" + +#include "iusace_cnst.h" +#include "iusace_tns_usac.h" +#include "iusace_psy_mod.h" +#include "iusace_psy_utils.h" +#include "iusace_fd_qc_util.h" +#include "ixheaace_memory_standards.h" +#include "iusace_tns_usac.h" +#include "iusace_config.h" +#include "iusace_arith_enc.h" +#include "iusace_fd_quant.h" +#include "iusace_ms.h" +#include "iusace_block_switch_const.h" +#include "iusace_block_switch_struct_def.h" +#include "iusace_signal_classifier.h" +#include "ixheaace_sbr_header.h" +#include "ixheaace_config.h" +#include "ixheaace_asc_write.h" +#include "iusace_main.h" +#include "iusace_write_bitstream.h" +#include "iusace_windowing.h" +#include "iusace_fd_enc.h" +#include "iusace_fd_qc_adjthr.h" +#include "iusace_config.h" +#include "iusace_tcx_mdct.h" +#include "iusace_func_prototypes.h" +#include "iusace_block_switch.h" +#include "iusace_rom.h" +#include "ixheaace_error_codes.h" + +#include "ixheaace_sbr_header.h" +#include "ixheaace_sbr_def.h" +#include "ixheaace_resampler.h" +#include "ixheaace_common_rom.h" + +#include "ixheaace_sbr_header.h" +#include "ixheaace_sbr_def.h" +#include "ixheaace_resampler.h" +#include "ixheaace_sbr_rom.h" +#include "ixheaace_common_rom.h" +#include "ixheaace_sbr_qmf_enc.h" +#include "ixheaace_sbr_tran_det.h" +#include "ixheaace_sbr_frame_info_gen.h" +#include "ixheaace_sbr_env_est.h" +#include "ixheaace_sbr_code_envelope.h" +#include "ixheaace_sbr_rom.h" +#include "ixheaace_sbr_main.h" +#include "ixheaace_common_rom.h" +#include "ixheaace_sbr_missing_harmonics_det.h" +#include "ixheaace_sbr_inv_filtering_estimation.h" +#include "ixheaace_sbr_noise_floor_est.h" +#include "ixheaace_sbr_ton_corr.h" +#include "iusace_esbr_pvc.h" +#include "iusace_esbr_inter_tes.h" +#include "ixheaace_sbr_hbe.h" +#include "ixheaace_sbr.h" +#include "ixheaace_sbr_cmondata.h" +#include "ixheaace_sbr_crc.h" +#include "ixheaace_sbr_enc_struct.h" + +#include "iusace_esbr_pvc.h" +#include "iusace_esbr_inter_tes.h" + +static WORD32 iusace_get_num_elements(WORD32 num_channels) { + WORD32 num_of_elements = 0; + + switch (num_channels) { + case 1: + case 2: + num_of_elements = 1; + break; + default: + num_of_elements = num_channels; + break; + } + + return num_of_elements; +} + +static UWORD32 iusace_get_element_type(WORD32 elem_idx, WORD32 num_channels) { + UWORD32 elem_type = (UWORD32)USAC_ELEMENT_TYPE_INVALID; + (VOID) elem_idx; + + switch (num_channels) { + case 1: + elem_type = USAC_ELEMENT_TYPE_SCE; + break; + case 2: + elem_type = USAC_ELEMENT_TYPE_CPE; + break; + default: + elem_type = USAC_ELEMENT_TYPE_SCE; + break; + } + + return elem_type; +} + +static VOID iusace_bw_init(ia_usac_encoder_config_struct *ptr_usac_config, + ixheaace_audio_specific_config_struct *pstr_asc, WORD32 ele_idx) { + ptr_usac_config->bw_limit[ele_idx] = 20000; + (VOID) pstr_asc; + ptr_usac_config->bw_limit[ele_idx] = + MIN(ptr_usac_config->bw_limit[ele_idx], ptr_usac_config->core_sample_rate / 2); + + return; +} + +VOID iusace_scratch_mem_init(ia_usac_data_struct *usac_data, WORD32 total_ch, WORD32 sr) { + iusace_scratch_mem *pstr_scratch = &usac_data->str_scratch; + UWORD8 *temp_ptr = pstr_scratch->ptr_scratch_buf; + + pstr_scratch->ptr_stack_mem = (FLOAT32 *)(temp_ptr); + temp_ptr += USACE_SCR_STACK; + + pstr_scratch->p_fd_mdct_windowed_long_buf = (FLOAT64 *)(temp_ptr); + temp_ptr += (2 * FRAME_LEN_LONG) * sizeof(FLOAT64); + + pstr_scratch->p_fd_mdct_windowed_short_buf = (FLOAT64 *)(temp_ptr); + // Size needed for above pointer is (2 * FRAME_LEN_LONG) * sizeof(FLOAT64) + + temp_ptr = (UWORD8 *)pstr_scratch->p_fd_mdct_windowed_short_buf; + + pstr_scratch->p_tns_filter = (FLOAT64 *)(temp_ptr); + temp_ptr += (FRAME_LEN_LONG) * sizeof(FLOAT64); + + pstr_scratch->ptr_tns_scratch = (FLOAT64 *)(temp_ptr); + temp_ptr += + (MAX_SHIFT_LEN_LONG + (TNS_MAX_ORDER + 1) * 2) * sizeof(pstr_scratch->ptr_tns_scratch[0]); + + pstr_scratch->p_left_fac_time_data = (FLOAT64 *)(temp_ptr); + temp_ptr += (2 * FAC_LENGTH + ORDER) * sizeof(FLOAT64); + + pstr_scratch->p_fac_win = (FLOAT64 *)(temp_ptr); + // Size needed for above pointer is (2 * FAC_LENGTH) * sizeof(FLOAT64) + + temp_ptr = (UWORD8 *)pstr_scratch->p_left_fac_time_data; + + pstr_scratch->p_sort_grouping_scratch = (FLOAT64 *)(temp_ptr); + // Size needed for above pointer is (LN2) * sizeof(FLOAT64) + + temp_ptr = (UWORD8 *)pstr_scratch->p_sort_grouping_scratch; + + pstr_scratch->p_noise_filling_highest_tone = (FLOAT64 *)(temp_ptr); + temp_ptr += (LN2) * sizeof(FLOAT64); + + pstr_scratch->p_quant_spectrum_spec_scratch = (FLOAT64 *)(temp_ptr); + temp_ptr += (2 * FRAME_LEN_LONG) * sizeof(FLOAT64); + + pstr_scratch->p_cmpx_mdct_temp_buf = (FLOAT64 *)(temp_ptr); + // Size needed for above pointer is (LN2) * sizeof(FLOAT64) + + temp_ptr = (UWORD8 *)pstr_scratch->p_noise_filling_highest_tone; + + for (WORD32 i = 0; i < total_ch; i++) { + pstr_scratch->p_reconstructed_time_signal[i] = (FLOAT64 *)(temp_ptr); + temp_ptr += (4 * FRAME_LEN_LONG) * sizeof(FLOAT64); + } + pstr_scratch->ptr_next_win_scratch = (WORD32 *)(temp_ptr); + temp_ptr += (2 * MAX_TIME_CHANNELS) * sizeof(pstr_scratch->ptr_next_win_scratch[0]); + + pstr_scratch->p_fft_p2_y = (FLOAT32 *)(temp_ptr); + temp_ptr += (2 * FRAME_LEN_LONG) * sizeof(FLOAT32); + + pstr_scratch->p_fft_p3_data_3 = (FLOAT32 *)(temp_ptr); + temp_ptr += (800) * sizeof(FLOAT32); + + pstr_scratch->p_fft_p3_y = (FLOAT32 *)(temp_ptr); + temp_ptr += (2 * FRAME_LEN_LONG) * sizeof(FLOAT32); + + pstr_scratch->p_time_signal = (FLOAT32 *)(temp_ptr); + temp_ptr += (FRAME_LEN_LONG) * sizeof(FLOAT32); + + pstr_scratch->p_complex_fft = (FLOAT32 *)(temp_ptr); + temp_ptr += (2 * FRAME_LEN_LONG) * sizeof(FLOAT32); + + pstr_scratch->p_tonal_flag = (WORD32 *)(temp_ptr); + temp_ptr += (FRAME_LEN_LONG / 2) * sizeof(WORD32); + + pstr_scratch->p_pow_spec = (FLOAT32 *)(temp_ptr); + // Size needed for above pointer is (FRAME_LEN_LONG / 2) * sizeof(FLOAT32) + temp_ptr = (UWORD8 *)pstr_scratch->p_time_signal; + + pstr_scratch->p_temp_mdct = (FLOAT32 *)(temp_ptr); + temp_ptr += (1024) * sizeof(FLOAT32); + + pstr_scratch->p_buf_synthesis_tool = (FLOAT32 *)(temp_ptr); + temp_ptr += (LEN_FRAME_16K + ORDER_LP_FILT_16K) * sizeof(FLOAT32); + + pstr_scratch->p_mdct_spec_float = (FLOAT32 *)(temp_ptr); + temp_ptr += (FRAME_LEN_LONG) * sizeof(FLOAT32); + + pstr_scratch->p_sq_gain_en = (FLOAT32 *)(temp_ptr); + temp_ptr += (FRAME_LEN_LONG / 4) * sizeof(FLOAT32); + + pstr_scratch->p_fft_mdct_buf = (FLOAT32 *)(temp_ptr); + temp_ptr += (4 * FRAME_LEN_LONG) * sizeof(FLOAT32); + + pstr_scratch->p_arith_map_prev_scratch = (WORD32 *)(temp_ptr); + temp_ptr += (516) * sizeof(WORD32); + + pstr_scratch->p_arith_map_pres_scratch = (WORD32 *)(temp_ptr); + temp_ptr += (516) * sizeof(WORD32); + + pstr_scratch->p_ol_pitch_buf_tmp = (FLOAT32 *)(temp_ptr); + temp_ptr += (FRAME_LEN_LONG) * sizeof(FLOAT32); + + pstr_scratch->p_ol_pitch_speech_buf = (FLOAT32 *)(temp_ptr); + temp_ptr += (FRAME_LEN_LONG + LAG_MAX) * sizeof(FLOAT32); + + pstr_scratch->p_ol_pitch_w_table = (FLOAT32 *)(temp_ptr); + temp_ptr += (LEN_CORR_R) * sizeof(FLOAT32); + + pstr_scratch->p_ol_pitch_R = (FLOAT32 *)(temp_ptr); + temp_ptr += (LEN_CORR_R) * sizeof(FLOAT32); + + WORD32 R0_size = (54 + 6 * ((WORD32)(34.f * ((FLOAT32)sr / 2.f) / 12800.f + 0.5f) * 2)) / 2; + pstr_scratch->p_ol_pitch_R0 = (FLOAT32 *)(temp_ptr); + temp_ptr += (R0_size) * sizeof(FLOAT32); + + pstr_scratch->p_lpd_frm_enc_scratch = (FLOAT32 *)(temp_ptr); + temp_ptr += (LEN_FRAME + 1) * sizeof(FLOAT32); + + pstr_scratch->p_wsig_buf = (FLOAT32 *)(temp_ptr + 128 * sizeof(FLOAT32)); + temp_ptr += (128 + FRAME_LEN_LONG) * sizeof(FLOAT32); + + pstr_scratch->p_wsyn_tcx_buf = (FLOAT32 *)(temp_ptr + 128 * sizeof(FLOAT32)); + temp_ptr += (128 + FRAME_LEN_LONG) * sizeof(FLOAT32); + + pstr_scratch->p_synth_tcx_buf = (FLOAT32 *)(temp_ptr + 128 * sizeof(FLOAT32)); + temp_ptr += (128 + FRAME_LEN_LONG) * sizeof(FLOAT32); + + pstr_scratch->p_wsyn_buf = (FLOAT32 *)(temp_ptr + 128 * sizeof(FLOAT32)); + temp_ptr += (128 + FRAME_LEN_LONG) * sizeof(FLOAT32); + + pstr_scratch->p_synth_buf = (FLOAT32 *)(temp_ptr + 128 * sizeof(FLOAT32)); + temp_ptr += (128 + FRAME_LEN_LONG) * sizeof(FLOAT32); + + pstr_scratch->p_temp_wsyn_buf = (FLOAT32 *)temp_ptr; + temp_ptr += (FRAME_LEN_LONG) * sizeof(FLOAT32); + + pstr_scratch->p_lp_filter_coeff = (FLOAT32 *)(temp_ptr); + temp_ptr += ((NUM_SUBFR_SUPERFRAME + 1) * (ORDER + 1)) * sizeof(FLOAT32); + + pstr_scratch->p_lp_filter_coeff_q = (FLOAT32 *)(temp_ptr); + temp_ptr += ((NUM_SUBFR_SUPERFRAME + 1) * (ORDER + 1)) * sizeof(FLOAT32); + + pstr_scratch->p_wsp_prev_buf = (FLOAT32 *)(temp_ptr); + temp_ptr += ((MAX_PITCH1 / OPL_DECIM) + LEN_FRAME) * sizeof(FLOAT32); + + pstr_scratch->ptr_lpd_scratch = (UWORD8 *)temp_ptr; + temp_ptr += ((2 * (NUM_SUBFR_SUPERFRAME + 1) * (ORDER + 1)) + (4 * (NUM_FRAMES + 1) * ORDER) + + (((NUM_FRAMES >> 1) + 1) * ORDER) * 4) * + sizeof(FLOAT32) + + 100 * sizeof(WORD32) + 6 * sizeof(ia_usac_lpd_scratch); + + pstr_scratch->p_prm_tcx = (WORD32 *)(temp_ptr); + temp_ptr += (NUM_TCX80_PRM) * sizeof(WORD32); + + pstr_scratch->p_buf_speech = (FLOAT32 *)(temp_ptr); + temp_ptr += (2 * LEN_FRAME + ORDER) * sizeof(FLOAT32); + + pstr_scratch->p_buf_res = (FLOAT32 *)(temp_ptr); + temp_ptr += (2 * LEN_FRAME) * sizeof(FLOAT32); + + pstr_scratch->p_buf_signal = (FLOAT32 *)(temp_ptr); + temp_ptr += (ORDER + LEN_FRAME) * sizeof(FLOAT32); + + pstr_scratch->p_xn1_tcx = (FLOAT32 *)(temp_ptr); + temp_ptr += (2 * FAC_LENGTH) * sizeof(FLOAT32); + + pstr_scratch->p_xn_buf_tcx = (FLOAT32 *)(temp_ptr); + temp_ptr += (128 + FRAME_LEN_LONG + 128) * sizeof(FLOAT32); + + pstr_scratch->p_x_tcx = (FLOAT32 *)(temp_ptr); + temp_ptr += (FRAME_LEN_LONG) * sizeof(FLOAT32); + + pstr_scratch->p_x_tmp_tcx = (FLOAT32 *)(temp_ptr); + temp_ptr += (FRAME_LEN_LONG) * sizeof(FLOAT32); + + pstr_scratch->p_en_tcx = (FLOAT32 *)(temp_ptr); + temp_ptr += (FRAME_LEN_LONG) * sizeof(FLOAT32); + + pstr_scratch->p_alfd_gains_tcx = (FLOAT32 *)(temp_ptr); + temp_ptr += (FRAME_LEN_LONG / (4 * 8)) * sizeof(FLOAT32); + + pstr_scratch->p_sq_enc_tcx = (FLOAT32 *)(temp_ptr); + temp_ptr += (FRAME_LEN_LONG) * sizeof(FLOAT32); + + pstr_scratch->p_sq_quant_tcx = (WORD32 *)(temp_ptr); + temp_ptr += (FRAME_LEN_LONG) * sizeof(WORD32); + + pstr_scratch->p_gain1_tcx = (FLOAT32 *)(temp_ptr); + temp_ptr += (FRAME_LEN_LONG) * sizeof(FLOAT32); + + pstr_scratch->p_gain2_tcx = (FLOAT32 *)(temp_ptr); + temp_ptr += (FRAME_LEN_LONG) * sizeof(FLOAT32); + + pstr_scratch->p_facelp_tcx = (FLOAT32 *)(temp_ptr); + temp_ptr += (FAC_LENGTH) * sizeof(FLOAT32); + + pstr_scratch->p_xn2_tcx = (FLOAT32 *)(temp_ptr); + temp_ptr += (2 * FAC_LENGTH) * sizeof(FLOAT32); + + pstr_scratch->p_fac_window_tcx = (FLOAT32 *)(temp_ptr); + temp_ptr += (2 * FAC_LENGTH) * sizeof(FLOAT32); + + pstr_scratch->p_x1_tcx = (FLOAT32 *)(temp_ptr); + temp_ptr += (FAC_LENGTH) * sizeof(FLOAT32); + + pstr_scratch->p_x2_tcx = (FLOAT32 *)(temp_ptr); + temp_ptr += (FAC_LENGTH) * sizeof(FLOAT32); + + pstr_scratch->p_y_tcx = (WORD32 *)(temp_ptr); + temp_ptr += (FAC_LENGTH) * sizeof(WORD32); + + pstr_scratch->p_in_out_tcx = (FLOAT32 *)(temp_ptr); + temp_ptr += (FRAME_LEN_LONG * 2 * 2) * sizeof(FLOAT32); + + pstr_scratch->p_tcx_input = (FLOAT32 *)(temp_ptr); + temp_ptr += (FRAME_LEN_LONG) * sizeof(FLOAT32); + + pstr_scratch->ptr_tcx_scratch = (FLOAT32 *)(temp_ptr); + temp_ptr += 3 * (FRAME_LEN_LONG) * sizeof(pstr_scratch->ptr_tcx_scratch[0]); + + pstr_scratch->p_tcx_output = (FLOAT32 *)(temp_ptr); + temp_ptr += (FRAME_LEN_LONG) * sizeof(FLOAT32); + + pstr_scratch->p_buf_aut_corr = (FLOAT32 *)(temp_ptr); + // Size needed for above pointer is (LEN_WIN_PLUS) * sizeof(FLOAT32) + temp_ptr = (UWORD8 *)pstr_scratch->p_buf_aut_corr; + + pstr_scratch->p_xn2 = (FLOAT32 *)(temp_ptr); + temp_ptr += (FAC_LENGTH + ORDER) * sizeof(FLOAT32); + + pstr_scratch->p_fac_dec = (FLOAT32 *)(temp_ptr); + temp_ptr += (2 * FAC_LENGTH) * sizeof(FLOAT32); + + pstr_scratch->p_right_fac_spec = (FLOAT32 *)(temp_ptr); + temp_ptr += (FAC_LENGTH) * sizeof(FLOAT32); + + pstr_scratch->p_x2 = (FLOAT32 *)(temp_ptr); + temp_ptr += (FAC_LENGTH) * sizeof(FLOAT32); + + pstr_scratch->p_param = (WORD32 *)(temp_ptr); + temp_ptr += (FAC_LENGTH + 1) * sizeof(WORD32); + + pstr_scratch->p_x = (FLOAT32 *)(temp_ptr); + temp_ptr += (FAC_LENGTH) * sizeof(FLOAT32); + + pstr_scratch->p_xn_2 = (FLOAT32 *)(temp_ptr); + temp_ptr += (2 * FAC_LENGTH + ORDER) * sizeof(FLOAT32); + + pstr_scratch->p_fac_window = (FLOAT32 *)(temp_ptr); + temp_ptr += (2 * FAC_LENGTH) * sizeof(FLOAT32); + + pstr_scratch->p_fir_sig_buf = (FLOAT32 *)(temp_ptr); + // Size needed for above pointer is (3 + LEN_FRAME) * sizeof(FLOAT32) + temp_ptr = (UWORD8 *)pstr_scratch->p_fir_sig_buf; + + pstr_scratch->p_acelp_ir_buf = (FLOAT32 *)(temp_ptr); + + temp_ptr += (4 * LEN_SUBFR) * sizeof(FLOAT32); + + pstr_scratch->ptr_acelp_scratch = (FLOAT32 *)(temp_ptr); + temp_ptr += ((11 * LEN_SUBFR) + (ORDER + LEN_SUBFR + 8) + 1024) * + sizeof(pstr_scratch->ptr_acelp_scratch[0]); + + pstr_scratch->p_acelp_exc_buf = (FLOAT32 *)(temp_ptr); + // Size needed for above pointer is ((3 * LEN_FRAME) + 1 + 41) * sizeof(FLOAT32) + + temp_ptr = (UWORD8 *)pstr_scratch->p_lpd_frm_enc_scratch; + + pstr_scratch->p_fac_bits_word = (WORD16 *)(temp_ptr); + temp_ptr += (5000) * sizeof(WORD16); + + pstr_scratch->p_left_fac_timedata_flt = (FLOAT32 *)(temp_ptr); + temp_ptr += (2 * FAC_LENGTH + ORDER) * sizeof(FLOAT32); + + pstr_scratch->p_left_fac_spec = (FLOAT32 *)(temp_ptr); + temp_ptr += (FAC_LENGTH) * sizeof(FLOAT32); + + pstr_scratch->p_fac_prm = (WORD32 *)(temp_ptr); + temp_ptr += (FAC_LENGTH + 1) * sizeof(WORD32); + + pstr_scratch->p_acelp_folded_scratch = (FLOAT32 *)(temp_ptr); + // Size needed for above pointer is (FAC_LENGTH) * sizeof(FLOAT32) + + temp_ptr = (UWORD8 *)pstr_scratch->p_fac_bits_word; + + pstr_scratch->p_exp_spec = (FLOAT32 *)(temp_ptr); + temp_ptr += (FRAME_LEN_LONG) * sizeof(FLOAT32); + + pstr_scratch->p_adjthr_ptr_exp_spec = (FLOAT32 *)(temp_ptr); + temp_ptr += (FRAME_LEN_LONG) * sizeof(FLOAT32); + + pstr_scratch->p_adjthr_mdct_spec_float = (FLOAT32 *)(temp_ptr); + temp_ptr += (FRAME_LEN_LONG) * sizeof(FLOAT32); + + pstr_scratch->p_adjthr_quant_spec_temp = (WORD16 *)(temp_ptr); + temp_ptr += (FRAME_LEN_LONG) * sizeof(WORD16); + + pstr_scratch->p_degroup_scratch = (WORD32 *)(temp_ptr); + temp_ptr += (FRAME_LEN_LONG) * sizeof(WORD32); + + /*Newly added*/ + pstr_scratch->ptr_drc_scratch_buf = (UWORD8 *)(temp_ptr); + + pstr_scratch->ptr_num_fac_bits = (WORD32 *)temp_ptr; + temp_ptr += MAX_TIME_CHANNELS * sizeof(pstr_scratch->ptr_num_fac_bits[0]); + pstr_scratch->ptr_tns_data_present = (WORD32 *)temp_ptr; + temp_ptr += MAX_TIME_CHANNELS * sizeof(pstr_scratch->ptr_tns_data_present[0]); + + pstr_scratch->ptr_tmp_lp_res = (FLOAT32 *)temp_ptr; + temp_ptr += FAC_LENGTH * sizeof(pstr_scratch->ptr_tmp_lp_res[0]); + + for (WORD32 i = 0; i < total_ch; i++) { + pstr_scratch->ptr_sfb_form_fac[i] = (FLOAT32 *)temp_ptr; + temp_ptr += (MAX_NUM_GROUPED_SFB) * sizeof(FLOAT32); + } + for (WORD32 i = 0; i < total_ch; i++) { + pstr_scratch->ptr_sfb_num_relevant_lines[i] = (FLOAT32 *)temp_ptr; + temp_ptr += (MAX_NUM_GROUPED_SFB) * sizeof(FLOAT32); + } + for (WORD32 i = 0; i < total_ch; i++) { + pstr_scratch->ptr_sfb_ld_energy[i] = (FLOAT32 *)temp_ptr; + temp_ptr += (MAX_NUM_GROUPED_SFB) * sizeof(FLOAT32); + } + pstr_scratch->ptr_num_scfs = (WORD32 *)temp_ptr; + temp_ptr += (MAX_TIME_CHANNELS) * sizeof(pstr_scratch->ptr_num_scfs[0]); + + pstr_scratch->ptr_max_ch_dyn_bits = (WORD32 *)temp_ptr; + temp_ptr += (MAX_TIME_CHANNELS) * sizeof(pstr_scratch->ptr_max_ch_dyn_bits[0]); + pstr_scratch->ptr_ch_bit_dist = (FLOAT32 *)temp_ptr; + temp_ptr += (MAX_TIME_CHANNELS) * sizeof(pstr_scratch->ptr_ch_bit_dist[0]); + pstr_scratch->ptr_fd_scratch = (UWORD8 *)temp_ptr; + // Size needed for above pointer is (IXHEAACE_MAX_CH_IN_BS_ELE * MAX_NUM_GROUPED_SFB * 3) * + // sizeof(WORD32) + + return; +} + +WORD32 iusace_limitbitrate(WORD32 core_sample_rate, WORD32 frame_len, WORD32 num_ch, + WORD32 bit_rate) { + WORD32 transport_bits, prev_bit_rate, shift = 0, iter = 0; + + while ((frame_len & ~((1 << (shift + 1)) - 1)) == frame_len && + (core_sample_rate & ~((1 << (shift + 1)) - 1)) == core_sample_rate) { + shift++; + } + + do { + prev_bit_rate = bit_rate; + /* Assume some worst case */ + transport_bits = 208; + + bit_rate = + MAX(bit_rate, ((((40 * num_ch) + transport_bits) * (core_sample_rate)) / frame_len)); + bit_rate = + MIN(bit_rate, ((num_ch * 6144) * (core_sample_rate >> shift)) / (frame_len >> shift)); + + } while (prev_bit_rate != bit_rate && iter++ < 3); + + return bit_rate; +} + +IA_ERRORCODE iusace_enc_init(ia_usac_encoder_config_struct *ptr_usac_config, + ixheaace_audio_specific_config_struct *pstr_asc, + ia_usac_data_struct *pstr_state) { + WORD32 err_code = 0; + WORD32 i, j, k, idx, i_ch; + UWORD32 elem_idx = 0; + ia_usac_data_struct *usac_data = (pstr_state); + ixheaace_audio_specific_config_struct *p_audio_specific_config = pstr_asc; + ia_usac_config_struct *pstr_asc_usac_config = &(p_audio_specific_config->str_usac_config); + WORD32 nbuff = 2048; + usac_data->usac_independency_flag_count = 0; + usac_data->usac_independency_flag_interval = 25; + for (j = 0; j < MAX_TIME_CHANNELS; j++) { + memset(usac_data->overlap_buf[j], 0, nbuff * sizeof(FLOAT64 *)); + + usac_data->str_ms_info[j].ms_mask = 0; + for (i = 0; i < MAX_SHORT_WINDOWS; i++) { + for (k = 0; k < MAX_SFB_LONG; k++) { + usac_data->str_ms_info[j].ms_used[i][k] = 0; + } + } + } + + iusace_scratch_mem_init(usac_data, ptr_usac_config->channels, + ptr_usac_config->core_sample_rate); + + for (i = 0; i < MAX_TIME_CHANNELS; i++) { + if (ptr_usac_config->cmplx_pred_flag) { + usac_data->str_ms_info[i].ms_mask = 3; + } + usac_data->ptr_dmx_re_save[i] = &usac_data->arr_dmx_save_float[i][0]; + usac_data->ptr_dmx_im[i] = &usac_data->arr_dmx_im[i][0]; + } + + pstr_asc_usac_config->num_elements = 0; + pstr_asc_usac_config->usac_cfg_ext_present = 0; + pstr_asc_usac_config->num_config_extensions = 0; + + if (ptr_usac_config->channels > 0) { + if (ptr_usac_config->channels < 7) { + p_audio_specific_config->channel_configuration = ptr_usac_config->channels; + } + } + + // DRC Config + if (ptr_usac_config->use_drc_element) { + ptr_usac_config->str_drc_cfg.str_uni_drc_config.str_channel_layout.base_ch_count = + ptr_usac_config->channels; + + memset(&usac_data->str_drc_state, 0, sizeof(ia_drc_enc_state)); + + err_code = impd_drc_enc_init(&usac_data->str_drc_state, pstr_state->str_scratch.drc_scratch, + &ptr_usac_config->str_drc_cfg); + if (err_code & IA_FATAL_ERROR) { + return err_code; + } + + ia_usac_enc_element_config_struct *pstr_usac_elem_config = + &(pstr_asc_usac_config->str_usac_element_config[pstr_asc_usac_config->num_elements]); + pstr_asc_usac_config->usac_element_type[pstr_asc_usac_config->num_elements] = ID_USAC_EXT; + pstr_usac_elem_config->usac_ext_ele_type = ID_EXT_ELE_UNI_DRC; + pstr_usac_elem_config->usac_ext_ele_dflt_len_present = 0; + pstr_usac_elem_config->usac_ext_ele_payload_present = 0; + pstr_usac_elem_config->drc_config_data = usac_data->str_drc_state.bit_buf_base_cfg; + pstr_usac_elem_config->usac_ext_ele_cfg_len = + (usac_data->str_drc_state.drc_config_data_size_bit + 7) >> 3; + pstr_asc_usac_config->num_elements++; + } + if (ptr_usac_config->use_drc_element) // For Loudness + { + pstr_asc_usac_config->usac_config_ext_type[pstr_asc_usac_config->num_config_extensions] = + ID_CONFIG_EXT_LOUDNESS_INFO; + pstr_asc_usac_config->usac_config_ext_len[pstr_asc_usac_config->num_config_extensions] = + (usac_data->str_drc_state.drc_config_ext_data_size_bit + 7) >> 3; + pstr_asc_usac_config->usac_config_ext_buf[pstr_asc_usac_config->num_config_extensions] = + usac_data->str_drc_state.bit_buf_base_cfg_ext; + pstr_asc_usac_config->num_config_extensions++; + pstr_asc_usac_config->usac_cfg_ext_present = 1; + } + + p_audio_specific_config->sampling_frequency = ptr_usac_config->native_sample_rate; + p_audio_specific_config->num_audio_channels = ptr_usac_config->channels; + elem_idx = pstr_asc_usac_config->num_elements; + ptr_usac_config->num_ext_elements = elem_idx; + pstr_asc_usac_config->num_ext_elements = elem_idx; + i = elem_idx; + + if (ptr_usac_config->channels != 0) { + ptr_usac_config->num_elements = iusace_get_num_elements(ptr_usac_config->channels); + pstr_asc_usac_config->num_elements += ptr_usac_config->num_elements; + + for (; i < (WORD32)pstr_asc_usac_config->num_elements; i++) { + pstr_asc_usac_config->usac_element_type[i] = iusace_get_element_type( + (i - ptr_usac_config->num_ext_elements), ptr_usac_config->channels); + } + } + + WORD32 count = ptr_usac_config->num_elements; + ptr_usac_config->num_elements = pstr_asc_usac_config->num_elements; + iusace_qc_create(&usac_data->str_qc_main); + + if (count > 2) { + WORD32 num_mono = 0, num_stereo = 0, num_lfe = 0; + + for (WORD8 ch_idx = 0; ch_idx < count; ch_idx++) { + switch ( + pstr_asc_usac_config->usac_element_type[ch_idx + ptr_usac_config->num_ext_elements]) { + case ID_USAC_SCE: + num_mono++; + break; + case ID_USAC_CPE: + num_stereo++; + break; + case ID_USAC_EXT: + break; + default: + return -1; + } + } + + WORD32 bitrate_per_stereo = (WORD32)((ptr_usac_config->basic_bitrate - (num_lfe)*8000) / + (num_mono * 0.625 + num_stereo)); + WORD32 bitrate_per_mono = (WORD32)(0.625 * bitrate_per_stereo); + + for (WORD8 ch_idx = 0; ch_idx < count; ch_idx++) { + switch ( + pstr_asc_usac_config->usac_element_type[ch_idx + ptr_usac_config->num_ext_elements]) { + case ID_USAC_SCE: + usac_data->str_qc_main.str_qc_data[ch_idx].ch_bitrate = bitrate_per_mono; + break; + case ID_USAC_CPE: + usac_data->str_qc_main.str_qc_data[ch_idx].ch_bitrate = bitrate_per_stereo; + break; + case ID_USAC_EXT: + break; + default: + return -1; + } + + usac_data->str_qc_main.str_qc_data[ch_idx].num_ch = 1; + if (ID_USAC_CPE == + pstr_asc_usac_config->usac_element_type[ch_idx + ptr_usac_config->num_ext_elements]) { + usac_data->str_qc_main.str_qc_data[ch_idx].num_ch = 2; + } + + usac_data->str_qc_main.str_qc_data[ch_idx].ch_bitrate = + MIN(360000 * usac_data->str_qc_main.str_qc_data[ch_idx].num_ch, + usac_data->str_qc_main.str_qc_data[ch_idx].ch_bitrate); + usac_data->str_qc_main.str_qc_data[ch_idx].ch_bitrate = + MAX(8000 * usac_data->str_qc_main.str_qc_data[ch_idx].num_ch, + usac_data->str_qc_main.str_qc_data[ch_idx].ch_bitrate); + + usac_data->str_qc_main.str_qc_data[ch_idx].ch_bitrate = + iusace_limitbitrate(ptr_usac_config->core_sample_rate, 512, + usac_data->str_qc_main.str_qc_data[ch_idx].num_ch, + usac_data->str_qc_main.str_qc_data[ch_idx].ch_bitrate); + + usac_data->str_qc_main.str_qc_data[ch_idx].avg_bits = + (usac_data->str_qc_main.str_qc_data[ch_idx].ch_bitrate * ptr_usac_config->ccfl) / + ptr_usac_config->core_sample_rate; + } + } else { + for (WORD8 ch_idx = 0; ch_idx < count; ch_idx++) { + usac_data->str_qc_main.str_qc_data[ch_idx].num_ch = (WORD8)ptr_usac_config->channels; + usac_data->str_qc_main.str_qc_data[ch_idx].ch_bitrate = ptr_usac_config->basic_bitrate; + usac_data->str_qc_main.str_qc_data[ch_idx].avg_bits = + (usac_data->str_qc_main.str_qc_data[ch_idx].ch_bitrate * ptr_usac_config->ccfl) / + ptr_usac_config->core_sample_rate; + } + } + + for (i_ch = 0; + i_ch < (WORD32)(ptr_usac_config->num_elements - ptr_usac_config->num_ext_elements); + i_ch++) { + iusace_bw_init(ptr_usac_config, p_audio_specific_config, i_ch); + + usac_data->noise_filling[i_ch] = ptr_usac_config->flag_noiseFilling; + } + + memset(&usac_data->str_psy_mod.str_psy_out_data, 0, + sizeof(ia_psy_mod_out_data_struct) * MAX_TIME_CHANNELS); + + i_ch = 0; + for (UWORD32 ch_idx = 0; + ch_idx < pstr_asc_usac_config->num_elements - ptr_usac_config->num_ext_elements; + ch_idx++) { + iusace_psy_mod_init( + &usac_data->str_psy_mod, (ptr_usac_config->core_sample_rate), + usac_data->str_qc_main.str_qc_data[ch_idx].ch_bitrate, ptr_usac_config->bw_limit[ch_idx], + usac_data->str_qc_main.str_qc_data[ch_idx].num_ch, i_ch, ch_idx, ptr_usac_config->ccfl); + i_ch += usac_data->str_qc_main.str_qc_data[ch_idx].num_ch; + } + + for (; elem_idx < pstr_asc_usac_config->num_elements; elem_idx++) { + idx = elem_idx - pstr_asc_usac_config->num_ext_elements; + pstr_asc_usac_config->str_usac_element_config[idx].noise_filling = + usac_data->noise_filling[idx]; + usac_data->channel_elem_type[idx] = pstr_asc_usac_config->usac_element_type[elem_idx]; + } + + if (ptr_usac_config->use_fill_element) { + ia_usac_enc_element_config_struct *pstr_usac_elem_config = + &(pstr_asc_usac_config->str_usac_element_config[pstr_asc_usac_config->num_elements]); + pstr_asc_usac_config->usac_element_type[pstr_asc_usac_config->num_elements] = ID_USAC_EXT; + pstr_usac_elem_config->usac_ext_ele_type = ID_EXT_ELE_FILL; + pstr_usac_elem_config->usac_ext_ele_cfg_len = 0; + pstr_usac_elem_config->usac_ext_ele_dflt_len_present = 0; + pstr_usac_elem_config->usac_ext_ele_payload_present = 0; + pstr_asc_usac_config->num_elements++; + } + + if (ptr_usac_config->codec_mode == USAC_SWITCHED) { + iusace_init_classification(&usac_data->str_sig_class_data); + } + + i_ch = 0; + for (UWORD32 ch_idx = 0; + ch_idx < pstr_asc_usac_config->num_elements - ptr_usac_config->num_ext_elements; + ch_idx++) { + for (idx = 0; idx < usac_data->str_qc_main.str_qc_data[ch_idx].num_ch; idx++, i_ch++) { + iusace_init_block_switching(&usac_data->block_switch_ctrl[i_ch], + usac_data->str_qc_main.str_qc_data[ch_idx].ch_bitrate, + usac_data->str_qc_main.str_qc_data[ch_idx].num_ch); + } + } + + pstr_asc_usac_config->str_usac_element_config[elem_idx].stereo_config_index = 0; + + for (i_ch = 0; i_ch < ptr_usac_config->channels; i_ch++) { + ptr_usac_config->window_sequence[i_ch] = ONLY_LONG_SEQUENCE; + ptr_usac_config->window_shape_prev[i_ch] = WIN_SEL_0; + } + + for (i_ch = 0; i_ch < ptr_usac_config->channels; i_ch++) { + memset(usac_data->td_in_buf[i_ch], 0, + (FRAME_LEN_LONG + LEN_NEXT_HIGH_RATE) * sizeof(usac_data->td_in_buf[i_ch][0])); + } + + usac_data->max_bitreservoir_bits = MAX_CHANNEL_BITS * ptr_usac_config->channels; + usac_data->available_bitreservoir_bits = usac_data->max_bitreservoir_bits; + usac_data->available_bitreservoir_bits -= + (ptr_usac_config->bit_rate * ptr_usac_config->ccfl) / ptr_usac_config->core_sample_rate; + + if (usac_data->available_bitreservoir_bits < 0) { + return IA_EXHEAACE_INIT_FATAL_USAC_BITRES_SIZE_TOO_SMALL; + } + i_ch = 0; + for (UWORD32 ch_idx = 0; + ch_idx < pstr_asc_usac_config->num_elements - ptr_usac_config->num_ext_elements; + ch_idx++) { + for (idx = 0; idx < usac_data->str_qc_main.str_qc_data[ch_idx].num_ch; idx++, i_ch++) { + usac_data->td_encoder[i_ch]->max_sfb_short = + usac_data->str_psy_mod.str_psy_short_config[ch_idx].sfb_count; + if (ptr_usac_config->tns_select == 0) { + usac_data->pstr_tns_info[i_ch] = NULL; + } else { + usac_data->pstr_tns_info[i_ch]->sfb_offset_table_short = + usac_data->str_psy_mod.str_psy_short_config[ch_idx].sfb_offset; + usac_data->pstr_tns_info[i_ch]->sfb_offset_table_long = + usac_data->str_psy_mod.str_psy_long_config[ch_idx].sfb_offset; + usac_data->pstr_tns_info[i_ch]->max_sfb_short = + usac_data->str_psy_mod.str_psy_short_config[ch_idx].sfb_count; + usac_data->pstr_tns_info[i_ch]->max_sfb_long = + usac_data->str_psy_mod.str_psy_long_config[ch_idx].sfb_count; + + if (iusace_tns_init(ptr_usac_config->core_sample_rate, + usac_data->str_qc_main.str_qc_data[ch_idx].ch_bitrate / + usac_data->str_qc_main.str_qc_data[ch_idx].num_ch, + usac_data->pstr_tns_info[i_ch], + usac_data->str_qc_main.str_qc_data[ch_idx].num_ch)) + return -1; + } + } + } + + for (i = 0; i < MAX_TIME_CHANNELS; i++) usac_data->str_quant_info[i].reset = 1; + + if (ptr_usac_config->codec_mode == USAC_SWITCHED || + ptr_usac_config->codec_mode == USAC_ONLY_TD) { + for (i_ch = 0; i_ch < ptr_usac_config->channels; i_ch++) { + if ((ptr_usac_config->core_sample_rate) < SR_MIN || + (ptr_usac_config->core_sample_rate) > SR_MAX) { + return IA_EXHEAACE_CONFIG_FATAL_USAC_SAMP_FREQ; + } else { + usac_data->td_encoder[i_ch]->fscale = ptr_usac_config->core_sample_rate; + + iusace_init_td_data(usac_data->td_encoder[i_ch], ptr_usac_config->ccfl); + } + + usac_data->td_bitrate[i_ch] = ptr_usac_config->bit_rate; + usac_data->td_bitrate[i_ch] /= ptr_usac_config->channels; + iusace_config_acelp_core_mode(usac_data->td_encoder[i_ch], + ptr_usac_config->core_sample_rate, + usac_data->td_bitrate[i_ch]); + + usac_data->acelp_core_mode[i_ch] = (usac_data->td_encoder[i_ch])->acelp_core_mode; + } + } else { + usac_data->acelp_core_mode[0] = 0; + } + + for (UWORD32 ch = 0; + ch < pstr_asc_usac_config->num_elements - ptr_usac_config->num_ext_elements; ch++) { + iusace_qc_init(&usac_data->str_qc_main.str_qc_data[ch], MAX_CHANNEL_BITS, + ptr_usac_config->core_sample_rate, ptr_usac_config->bw_limit[ch], + usac_data->str_qc_main.str_qc_data[ch].num_ch, ptr_usac_config->ccfl); + } + + return err_code; +} + +static WORD32 iexheaax_append_bitstream(ixheaace_bit_buf_handle hdl_bitbuf_write, + ixheaace_bit_buf_handle hdl_bitbuf_read, + WORD32 num_bits) { + WORD32 idx; + UWORD32 value; + + if (num_bits > 16) { + WORD32 cnt, rem; + cnt = num_bits >> 4; + rem = num_bits % 16; + + for (idx = 0; idx < cnt; idx++) { + value = ixheaace_readbits(hdl_bitbuf_read, 16); + ixheaace_write_bits(hdl_bitbuf_write, value, 16); + } + if (rem) { + value = ixheaace_readbits(hdl_bitbuf_read, (UWORD8)rem); + ixheaace_write_bits(hdl_bitbuf_write, value, (UWORD8)rem); + } + } else { + value = ixheaace_readbits(hdl_bitbuf_read, (UWORD8)num_bits); + ixheaace_write_bits(hdl_bitbuf_write, value, (UWORD8)num_bits); + } + + return num_bits; +} + +static IA_ERRORCODE iusace_enc_ext_elemts(UWORD32 usac_ext_ele_type, + ia_usac_encoder_config_struct *pstr_usac_config, + ia_usac_data_struct *pstr_usac_data, + ixheaace_audio_specific_config_struct *pstr_asc, + FLOAT32 **pptr_input, ia_bit_buf_struct *it_bit_buff, + WORD32 *num_bits_written) { + WORD8 idx = 0; + LOOPIDX idx_2 = 0; + WORD32 num_bits_payload = 0; + WORD32 num_byts_payload = 0; + ia_usac_config_struct *pstr_asc_usac_config = &(pstr_asc->str_usac_config); + VOID *pstr_scratch = &pstr_usac_data->str_scratch; + IA_ERRORCODE err_code = IA_NO_ERROR; + + for (idx = 0; idx < (WORD32)pstr_asc_usac_config->num_elements; idx++) { + if (ID_USAC_EXT != pstr_asc_usac_config->usac_element_type[idx]) { + continue; + } + + ia_usac_enc_element_config_struct *pstr_usac_elem_config = + &(pstr_asc_usac_config->str_usac_element_config[idx]); + + if (usac_ext_ele_type != pstr_usac_elem_config->usac_ext_ele_type) { + continue; + } + + switch (pstr_usac_elem_config->usac_ext_ele_type) { + case ID_EXT_ELE_UNI_DRC: { + if (pstr_usac_data->str_drc_state.is_first_drc_process_complete == 0) { + iusace_reset_bit_buffer(&pstr_usac_data->str_drc_state.str_bit_buf_out); + impd_drc_enc(&pstr_usac_data->str_drc_state, pptr_input, 0, &num_bits_payload, + pstr_scratch); + + pstr_usac_data->str_drc_state.is_first_drc_process_complete = 1; + num_bits_payload = 0; + } + + iusace_reset_bit_buffer(&pstr_usac_data->str_drc_state.str_bit_buf_out); + impd_drc_enc(&pstr_usac_data->str_drc_state, pptr_input, pstr_usac_config->drc_frame_size, + &num_bits_payload, pstr_scratch); + + num_byts_payload = (num_bits_payload + 7) >> 3; + } break; + default: { + } break; + } + + if (num_byts_payload <= 0) { + *num_bits_written += iusace_write_bits_buf(it_bit_buff, 0, 1); // usacExtElementPresent + } else { + *num_bits_written += iusace_write_bits_buf(it_bit_buff, 1, 1); // usacExtElementPresent + + *num_bits_written += + iusace_write_bits_buf(it_bit_buff, 0, 1); // usacExtElementUseDefaultLength + + if (num_byts_payload >= 255) { + *num_bits_written += + iusace_write_bits_buf(it_bit_buff, 255, 8); // usacExtElementPayloadLength + + UWORD16 value_add = (UWORD16)(num_byts_payload - 255 + 2); + *num_bits_written += iusace_write_bits_buf(it_bit_buff, value_add, 16); + } else { + *num_bits_written += iusace_write_bits_buf(it_bit_buff, num_byts_payload, + 8); // usacExtElementPayloadLength + } + + switch (pstr_usac_elem_config->usac_ext_ele_type) { + case ID_EXT_ELE_UNI_DRC: { + for (idx_2 = 0; idx_2 < num_byts_payload; idx_2++) { + *num_bits_written += iusace_write_bits_buf( + it_bit_buff, pstr_usac_data->str_drc_state.bit_buf_base_out[idx_2], 8); + } + } break; + default: { + } break; + } + } + } + + return err_code; +} + +IA_ERRORCODE ixheaace_usac_encode(FLOAT32 **ptr_input, + ia_usac_encoder_config_struct *ptr_usac_config, + ia_usac_data_struct *pstr_state, + ixheaace_audio_specific_config_struct *pstr_asc, + ia_bit_buf_struct *pstr_it_bit_buff, + ixheaace_pstr_sbr_enc ptr_env_encoder, FLOAT32 **pp_drc_inp) { + IA_ERRORCODE err = IA_NO_ERROR; + WORD32 i_ch, i, k; + ia_usac_data_struct *ptr_usac_data = pstr_state; + iusace_scratch_mem *pstr_scratch = &ptr_usac_data->str_scratch; + WORD32 bits_written = 0; + + WORD32 *next_window_sequence = pstr_scratch->ptr_next_win_scratch; + WORD32 *new_win_seq = pstr_scratch->ptr_next_win_scratch + MAX_TIME_CHANNELS; + memset(next_window_sequence, 0, MAX_TIME_CHANNELS * sizeof(next_window_sequence)); + memset(new_win_seq, 0, MAX_TIME_CHANNELS * sizeof(new_win_seq)); + ia_sfb_params_struct *pstr_sfb_prms = &ptr_usac_config->str_sfb_prms; + memset(pstr_sfb_prms, 0, sizeof(ia_sfb_params_struct)); + + WORD32 *num_window_groups = pstr_sfb_prms->num_window_groups; + WORD32 average_bits_total; + WORD32 min_bits_needed; + WORD32 num_bits; + WORD32 padding_bits; + WORD32 *common_win = pstr_sfb_prms->common_win; + WORD32 usac_independency_flg; + WORD32 mod[NUM_FRAMES] = {0}; + WORD32 len_frame; + WORD32 len_lpc0; + WORD32 len_next_high_rate; + WORD8 elem_idx, nr_core_coder_channels = 0, chn = 0; + WORD32 ch_offset = 0; + WORD32 elem_idx_max = ptr_usac_config->num_elements; + WORD32 td_buffer_offset = (TD_BUFFER_OFFSET * ptr_usac_config->ccfl) / FRAME_LEN_LONG; + usac_independency_flg = ptr_usac_data->usac_independency_flag; + + len_frame = ptr_usac_config->ccfl; + len_lpc0 = (LEN_LPC0 * len_frame) / FRAME_LEN_LONG; + len_next_high_rate = (LEN_NEXT_HIGH_RATE * len_frame) / FRAME_LEN_LONG; + + average_bits_total = + (ptr_usac_config->bit_rate * ptr_usac_config->ccfl) / ptr_usac_config->core_sample_rate; + + min_bits_needed = (long)(ptr_usac_data->available_bitreservoir_bits + 2 * average_bits_total - + ptr_usac_data->max_bitreservoir_bits); + if (min_bits_needed < 0) { + min_bits_needed = 0; + } + + if (ptr_usac_config->use_drc_element == 1) { + elem_idx_max -= 1; + } + + num_bits = 0; + + iusace_write_bits_buf(pstr_it_bit_buff, usac_independency_flg, 1); + num_bits++; + + for (elem_idx = 0; elem_idx < elem_idx_max; elem_idx++) { + switch (ptr_usac_data->channel_elem_type[elem_idx]) { + case USAC_ELEMENT_TYPE_SCE: + nr_core_coder_channels = 1; + break; + case USAC_ELEMENT_TYPE_CPE: + nr_core_coder_channels = 2; + break; + } + + if (ptr_usac_data->core_mode[0] == CORE_MODE_FD) { + for (chn = 0, i_ch = ch_offset; chn < nr_core_coder_channels; chn++, i_ch++) { + iusace_block_switching(&ptr_usac_data->block_switch_ctrl[i_ch], ptr_input[i_ch], + ptr_usac_config->ccfl); + } + } + + i_ch = ch_offset; + if (nr_core_coder_channels == 2) { + iusace_sync_block_switching(&ptr_usac_data->block_switch_ctrl[i_ch], + &ptr_usac_data->block_switch_ctrl[i_ch + 1]); + } + + for (chn = 0, i_ch = ch_offset; chn < nr_core_coder_channels; chn++, i_ch++) { + switch (ptr_usac_config->codec_mode) { + case USAC_SWITCHED: + if (ptr_usac_data->str_sig_class_data.coding_mode == 2) { + ptr_usac_data->core_mode_next[i_ch] = CORE_MODE_FD; + } else { + ptr_usac_data->core_mode_next[i_ch] = CORE_MODE_TD; + } + break; + case USAC_ONLY_FD: + ptr_usac_data->core_mode_next[i_ch] = CORE_MODE_FD; + break; + case USAC_ONLY_TD: + ptr_usac_data->core_mode_next[i_ch] = CORE_MODE_TD; + break; + default: + return (-1); + } + if (ptr_usac_data->core_mode[i_ch] == CORE_MODE_TD) { + for (i = 0; i < ptr_usac_config->ccfl; i++) { + ptr_usac_data->ptr_2frame_time_data[i_ch][i] = ptr_usac_data->ptr_time_data[i_ch][i]; + ptr_usac_data->ptr_2frame_time_data[i_ch][ptr_usac_config->ccfl + i] = + ptr_usac_data->ptr_look_ahead_time_data[i_ch][i]; + ptr_usac_data->ptr_time_data[i_ch][i] = + ptr_usac_data->ptr_look_ahead_time_data[i_ch][i]; + ptr_usac_data->ptr_look_ahead_time_data[i_ch][i] = (FLOAT64)ptr_input[i_ch][i]; + } + } else { + for (i = 0; i < ptr_usac_config->ccfl; i++) { + ptr_usac_data->ptr_2frame_time_data[i_ch][i] = ptr_usac_data->ptr_time_data[i_ch][i]; + ptr_usac_data->ptr_2frame_time_data[i_ch][ptr_usac_config->ccfl + i] = + ptr_usac_data->ptr_look_ahead_time_data[i_ch][i]; + ptr_usac_data->ptr_time_data[i_ch][i] = ptr_input[i_ch][i]; + ptr_usac_data->ptr_look_ahead_time_data[i_ch][i] = (FLOAT64)ptr_input[i_ch][i]; + } + } + + for (i = 0; i < len_frame + len_next_high_rate; i++) { + ptr_usac_data->td_in_buf[i_ch][i] = + (FLOAT32)(ptr_usac_data->ptr_2frame_time_data[i_ch][i + td_buffer_offset]); + } + for (i = 0; i < len_frame + len_next_high_rate + len_lpc0; i++) { + ptr_usac_data->td_in_prev_buf[i_ch][i] = + (FLOAT32)(ptr_usac_data->ptr_2frame_time_data[i_ch][i + td_buffer_offset - len_lpc0]); + } + + if (ptr_usac_data->core_mode[i_ch] == CORE_MODE_FD) { + ptr_usac_data->window_size_samples[i_ch] = ptr_usac_config->ccfl; + pstr_sfb_prms->window_sequence[i_ch] = ptr_usac_data->block_switch_ctrl[i_ch].window_seq; + ptr_usac_config->window_sequence[i_ch] = pstr_sfb_prms->window_sequence[i_ch]; + new_win_seq[i_ch] = ptr_usac_data->block_switch_ctrl[i_ch].next_win_seq; + } + + err = iusace_sfb_params_init(ptr_usac_config->core_sample_rate, ptr_usac_config->ccfl, + pstr_sfb_prms->sfb_width_table[i_ch], + &pstr_sfb_prms->num_sfb[i_ch], + pstr_sfb_prms->window_sequence[i_ch]); + + if (err) { + return err; + } + + pstr_sfb_prms->sfb_offset[i_ch][0] = 0; + k = 0; + for (i = 0; i < pstr_sfb_prms->num_sfb[i_ch]; i++) { + pstr_sfb_prms->sfb_offset[i_ch][i] = k; + k += pstr_sfb_prms->sfb_width_table[i_ch][i]; + } + pstr_sfb_prms->sfb_offset[i_ch][i] = k; + + if (ptr_usac_data->core_mode[i_ch] != CORE_MODE_TD) { + next_window_sequence[i_ch] = new_win_seq[i_ch]; + if (ptr_usac_data->core_mode_next[i_ch] == CORE_MODE_TD) { + next_window_sequence[i_ch] = EIGHT_SHORT_SEQUENCE; + } + + if (ptr_usac_data->core_mode[i_ch] == CORE_MODE_TD && + ptr_usac_data->core_mode_next[i_ch] != CORE_MODE_TD) { + next_window_sequence[i_ch] = LONG_STOP_SEQUENCE; + } + + if (next_window_sequence[i_ch] == EIGHT_SHORT_SEQUENCE) { + if (pstr_sfb_prms->window_sequence[i_ch] == ONLY_LONG_SEQUENCE) { + pstr_sfb_prms->window_sequence[i_ch] = LONG_START_SEQUENCE; + } + if (pstr_sfb_prms->window_sequence[i_ch] == LONG_STOP_SEQUENCE) { + pstr_sfb_prms->window_sequence[i_ch] = STOP_START_SEQUENCE; + } + } + + if (next_window_sequence[i_ch] == ONLY_LONG_SEQUENCE) { + if (pstr_sfb_prms->window_sequence[i_ch] == EIGHT_SHORT_SEQUENCE) { + next_window_sequence[i_ch] = LONG_STOP_SEQUENCE; + } + } + + if (pstr_sfb_prms->window_sequence[i_ch] == EIGHT_SHORT_SEQUENCE) { + num_window_groups[i_ch] = ptr_usac_data->block_switch_ctrl[i_ch].tot_grps_cnt; + for (i = 0; i < 8; i++) { + pstr_sfb_prms->window_group_length[i_ch][i] = + ptr_usac_data->block_switch_ctrl[i_ch].group_len[i]; + } + } else { + num_window_groups[i_ch] = 1; + pstr_sfb_prms->window_group_length[i_ch][0] = 1; + } + + pstr_sfb_prms->window_shape[i_ch] = ptr_usac_config->window_shape_prev[i_ch]; + + err = iusace_fd_mdct(ptr_usac_data, ptr_usac_config, i_ch); + + if (err) { + return err; + } + + if (pstr_sfb_prms->window_sequence[i_ch] != EIGHT_SHORT_SEQUENCE) { + iusace_psy_mod_lb(&ptr_usac_data->str_psy_mod, pstr_sfb_prms, + ptr_usac_data->spectral_line_vector[i_ch], + ptr_usac_data->pstr_tns_info, ptr_usac_config->tns_select, i_ch, chn, + ptr_usac_data->channel_elem_type[elem_idx], + pstr_scratch->p_tns_filter, elem_idx, pstr_scratch->ptr_tns_scratch, + ptr_usac_config->ccfl); + } else { + iusace_psy_mod_sb(&(ptr_usac_data->str_psy_mod), pstr_sfb_prms, + ptr_usac_data->spectral_line_vector[i_ch], + ptr_usac_data->pstr_tns_info, ptr_usac_config->tns_select, i_ch, chn, + ptr_usac_data->channel_elem_type[elem_idx], + pstr_scratch->p_tns_filter, elem_idx, pstr_scratch->ptr_tns_scratch, + ptr_usac_config->ccfl); + } + + pstr_sfb_prms->max_sfb[i_ch] = + ptr_usac_data->str_psy_mod.str_psy_out_data[i_ch].max_sfb_per_grp; + } + } + for (chn = 0, i_ch = ch_offset; chn < nr_core_coder_channels; chn++, i_ch++) { + if (nr_core_coder_channels == 2) { + if ((pstr_sfb_prms->window_shape[i_ch] == pstr_sfb_prms->window_shape[i_ch + 1]) && + (pstr_sfb_prms->window_sequence[i_ch] == pstr_sfb_prms->window_sequence[i_ch + 1]) && + (ptr_usac_data->core_mode[i_ch] == ptr_usac_data->core_mode[i_ch + 1])) { + common_win[i_ch] = common_win[i_ch + 1] = 1; + } else { + common_win[i_ch] = 0; + } + chn++; + } else { + common_win[i_ch] = 0; + } + } + if (nr_core_coder_channels == 2) { + if (i_ch == (ch_offset + 1)) { + if (pstr_sfb_prms->window_sequence[i_ch] != EIGHT_SHORT_SEQUENCE) { + iusace_calc_ms_band_energy( + ptr_usac_data->spectral_line_vector[ch_offset], + ptr_usac_data->spectral_line_vector[ch_offset + 1], + ptr_usac_data->str_psy_mod.str_psy_long_config[elem_idx].sfb_offset, + ptr_usac_data->str_psy_mod.str_psy_long_config[elem_idx].sfb_active, + ptr_usac_data->str_psy_mod.str_psy_data[ch_offset].ptr_sfb_energy_long_ms, + ptr_usac_data->str_psy_mod.str_psy_data[ch_offset + 1].ptr_sfb_energy_long_ms); + } else { + WORD32 frame_len_short = (ptr_usac_config->ccfl * FRAME_LEN_SHORT_128) / FRAME_LEN_LONG; + for (WORD32 w = 0; w < MAX_SHORT_WINDOWS; w++) { + WORD32 w_offset = w * frame_len_short; + + iusace_calc_ms_band_energy( + ptr_usac_data->spectral_line_vector[ch_offset] + w_offset, + ptr_usac_data->spectral_line_vector[ch_offset + 1] + w_offset, + ptr_usac_data->str_psy_mod.str_psy_short_config[elem_idx].sfb_offset, + ptr_usac_data->str_psy_mod.str_psy_short_config[elem_idx].sfb_active, + ptr_usac_data->str_psy_mod.str_psy_data[ch_offset].ptr_sfb_energy_short_ms[w], + ptr_usac_data->str_psy_mod.str_psy_data[ch_offset + 1] + .ptr_sfb_energy_short_ms[w]); + } + } + } + } + if ((nr_core_coder_channels == 2) + ? ((ptr_usac_data->core_mode[ch_offset] == CORE_MODE_FD) && + (ptr_usac_data->core_mode[ch_offset + 1] == CORE_MODE_FD)) + : ((ptr_usac_data->core_mode[ch_offset] == CORE_MODE_FD))) { + iusace_grouping(pstr_sfb_prms, nr_core_coder_channels, ptr_usac_data, ptr_usac_config, + ch_offset, elem_idx); + + if (nr_core_coder_channels == 2) { + err = iusace_stereo_proc(pstr_sfb_prms, usac_independency_flg, ptr_usac_data, + ptr_usac_config, ch_offset); + if (err != IA_NO_ERROR) { + return err; + } + } + } + + if (ptr_usac_config->use_drc_element) { + WORD32 num_bits_ext_elem = 0; + err = iusace_enc_ext_elemts(ID_EXT_ELE_UNI_DRC, ptr_usac_config, pstr_state, pstr_asc, + pp_drc_inp, pstr_it_bit_buff, &num_bits_ext_elem); + if (err & IA_FATAL_ERROR) { + return err; + } + num_bits += num_bits_ext_elem; +#ifdef DRC_BITRATE_CONSIDERATION + ptr_usac_data->drc_data_bit_cnt = num_bits_ext_elem; +#endif + } + + for (chn = 0, i_ch = ch_offset; chn < nr_core_coder_channels; chn++, i_ch++) { + iusace_write_bits_buf(pstr_it_bit_buff, ptr_usac_data->core_mode[i_ch], 1); + num_bits++; + } + + for (chn = 0, i_ch = ch_offset; chn < nr_core_coder_channels; chn++, i_ch++) { + if (ptr_usac_data->core_mode[i_ch] == CORE_MODE_FD) { + ptr_usac_data->window_size_samples[i_ch] = ptr_usac_config->ccfl; + pstr_sfb_prms->window_sequence[i_ch] = ptr_usac_data->block_switch_ctrl[i_ch].window_seq; + ptr_usac_config->window_sequence[i_ch] = pstr_sfb_prms->window_sequence[i_ch]; + new_win_seq[i_ch] = ptr_usac_data->block_switch_ctrl[i_ch].next_win_seq; + } + + if (ptr_usac_data->core_mode[i_ch] == CORE_MODE_TD) { + WORD32 error; + + error = iusace_lpd_frm_enc(ptr_usac_data, mod, usac_independency_flg, + len_frame, i_ch, pstr_it_bit_buff); + if (error) return error; + + num_bits = pstr_it_bit_buff->cnt_bits; + + if ((ptr_usac_data->core_mode_prev[i_ch] == CORE_MODE_FD) && (mod[0] == 0)) { + for (i = 0; i < ptr_usac_data->num_td_fac_bits[i_ch]; i++) { + iusace_write_bits_buf(pstr_it_bit_buff, ptr_usac_data->fac_out_stream[i_ch][i], 1); + num_bits++; + } + } + } else { + next_window_sequence[i_ch] = new_win_seq[i_ch]; + if (ptr_usac_data->core_mode_next[i_ch] == CORE_MODE_TD) { + next_window_sequence[i_ch] = EIGHT_SHORT_SEQUENCE; + } + + if (ptr_usac_data->core_mode[i_ch] == CORE_MODE_TD && + ptr_usac_data->core_mode_next[i_ch] != CORE_MODE_TD) { + next_window_sequence[i_ch] = LONG_STOP_SEQUENCE; + } + + if (next_window_sequence[i_ch] == EIGHT_SHORT_SEQUENCE) { + if (pstr_sfb_prms->window_sequence[i_ch] == ONLY_LONG_SEQUENCE) { + pstr_sfb_prms->window_sequence[i_ch] = LONG_START_SEQUENCE; + } + if (pstr_sfb_prms->window_sequence[i_ch] == LONG_STOP_SEQUENCE) { + pstr_sfb_prms->window_sequence[i_ch] = STOP_START_SEQUENCE; + } + } + if (next_window_sequence[i_ch] == ONLY_LONG_SEQUENCE) { + if (pstr_sfb_prms->window_sequence[i_ch] == EIGHT_SHORT_SEQUENCE) { + next_window_sequence[i_ch] = LONG_STOP_SEQUENCE; + } + } + if (pstr_sfb_prms->window_sequence[i_ch] == EIGHT_SHORT_SEQUENCE) { + num_window_groups[i_ch] = ptr_usac_data->block_switch_ctrl[i_ch].tot_grps_cnt; + for (i = 0; i < 8; i++) { + pstr_sfb_prms->window_group_length[i_ch][i] = + ptr_usac_data->block_switch_ctrl[i_ch].group_len[i]; + } + } else { + num_window_groups[i_ch] = 1; + pstr_sfb_prms->window_group_length[i_ch][0] = 1; + } + pstr_sfb_prms->window_shape[i_ch] = ptr_usac_config->window_shape_prev[i_ch]; + } + } + + if ((nr_core_coder_channels == 2) + ? ((ptr_usac_data->core_mode[ch_offset] == CORE_MODE_FD) && + (ptr_usac_data->core_mode[ch_offset + 1] == CORE_MODE_FD)) + : ((ptr_usac_data->core_mode[ch_offset] == CORE_MODE_FD))) { + err = iusace_fd_encode(pstr_sfb_prms, usac_independency_flg, ptr_usac_data, ptr_usac_config, + pstr_it_bit_buff, nr_core_coder_channels, ch_offset, elem_idx, + &bits_written); + + if (err) { + return err; + } + + num_bits += bits_written; + } + + for (chn = 0, i_ch = ch_offset; chn < nr_core_coder_channels; chn++, i_ch++) { + ptr_usac_config->window_shape_prev[i_ch] = pstr_sfb_prms->window_shape[i_ch]; + ptr_usac_config->window_sequence_prev[i_ch] = ptr_usac_config->window_sequence[i_ch]; + ptr_usac_config->window_sequence[i_ch] = next_window_sequence[i_ch]; + ptr_usac_data->core_mode_prev[i_ch] = ptr_usac_data->core_mode[i_ch]; + ptr_usac_data->core_mode[i_ch] = ptr_usac_data->core_mode_next[i_ch]; + } + ch_offset += nr_core_coder_channels; + } + + if (1 == ptr_usac_config->sbr_enable) { + // Append SBR bits + ixheaace_bit_buf_handle pstr_it_bit_buff_temp = + &ptr_env_encoder->str_cmon_data.str_sbr_bit_buf; + WORD32 check_num_bits = ia_enhaacplus_enc_get_bits_available(pstr_it_bit_buff_temp); + + num_bits += iexheaax_append_bitstream((ixheaace_bit_buf_handle)pstr_it_bit_buff, + pstr_it_bit_buff_temp, check_num_bits); + } + + if (ptr_usac_config->use_fill_element) { + WORD32 full_elem_num_bits = 0; + padding_bits = min_bits_needed - num_bits; + full_elem_num_bits = iusace_write_fill_ele(pstr_it_bit_buff, padding_bits); + num_bits += full_elem_num_bits; + } + + ptr_usac_data->available_bitreservoir_bits -= num_bits; + + if (num_bits % 8) { + ptr_usac_data->available_bitreservoir_bits -= 8 - (num_bits % 8); + } + ptr_usac_data->available_bitreservoir_bits += average_bits_total; + + if (ptr_usac_data->available_bitreservoir_bits > ptr_usac_data->max_bitreservoir_bits) { + ptr_usac_data->available_bitreservoir_bits = ptr_usac_data->max_bitreservoir_bits; + } + + return 0; +} diff --git a/encoder/iusace_esbr_inter_tes.c b/encoder/iusace_esbr_inter_tes.c new file mode 100644 index 0000000..1229a46 --- /dev/null +++ b/encoder/iusace_esbr_inter_tes.c @@ -0,0 +1,793 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include + +#include "ixheaac_type_def.h" +#include "ixheaac_constants.h" +#include "ixheaace_aac_constants.h" +#include "ixheaac_basic_ops32.h" +#include "ixheaac_basic_ops16.h" +#include "ixheaac_basic_ops40.h" +#include "ixheaac_error_standards.h" +#include "ixheaace_error_codes.h" + +#include "ixheaace_bitbuffer.h" +#include "ixheaace_sbr_def.h" +#include "iusace_esbr_inter_tes.h" +#include "iusace_esbr_rom.h" + +VOID ixheaace_init_esbr_inter_tes(ixheaace_str_inter_tes_params *pstr_tes_enc, + WORD32 sbr_ratio_index) { + WORD32 ts; + WORD32 memset_sz = IXHEAACE_QMF_CHANNELS * sizeof(pstr_tes_enc->qmf_buf_real[0][0]); + + switch (sbr_ratio_index) { + case USAC_SBR_RATIO_INDEX_2_1: + pstr_tes_enc->op_delay = 6; + pstr_tes_enc->codec_delay = 32; + pstr_tes_enc->sbr_ratio_index = sbr_ratio_index; + break; + case USAC_SBR_RATIO_INDEX_4_1: + pstr_tes_enc->op_delay = 6 * 2; + pstr_tes_enc->codec_delay = 64; + pstr_tes_enc->sbr_ratio_index = sbr_ratio_index; + break; + } + + memset(&pstr_tes_enc->bw_array_prev[0], 0, + IXHEAACE_MAX_NUM_PATCHES * sizeof(pstr_tes_enc->bw_array_prev[0])); + memset(&pstr_tes_enc->inv_filt_mode_prev[0], 0, + IXHEAACE_MAX_NUM_NOISE_VALUES * sizeof(pstr_tes_enc->inv_filt_mode_prev[0])); + + for (ts = 0; + ts < pstr_tes_enc->op_delay + pstr_tes_enc->codec_delay + IXHEAACE_SBR_HF_ADJ_OFFSET; + ts++) { + memset(pstr_tes_enc->qmf_buf_real[ts], 0, memset_sz); + memset(pstr_tes_enc->qmf_buf_imag[ts], 0, memset_sz); + } + return; +} + +static VOID ixheaace_apply_inter_tes(FLOAT32 *qmf_real1, FLOAT32 *qmf_imag1, FLOAT32 *qmf_real, + FLOAT32 *qmf_imag, WORD32 num_sample, WORD32 sub_band_start, + WORD32 num_subband, WORD32 gamma_idx) { + WORD32 sub_band_end = sub_band_start + num_subband; + FLOAT32 subsample_power_high[IXHEAACE_TIMESLOT_BUFFER_SIZE], + subsample_power_low[IXHEAACE_TIMESLOT_BUFFER_SIZE]; + FLOAT32 total_power_high = 0.0f; + FLOAT32 total_power_low = 0.0f, total_power_high_after = 1.0e-6f; + FLOAT32 gain[IXHEAACE_TIMESLOT_BUFFER_SIZE]; + FLOAT32 gain_adj, gain_adj_2; + FLOAT32 gamma = ixheaace_gamma_tab[gamma_idx]; + WORD32 i, j; + WORD32 memcpy_sz = sub_band_start * sizeof(FLOAT32); + + if (gamma > 0) { + for (i = 0; i < num_sample; i++) { + memcpy(&qmf_real[IXHEAACE_QMF_CHANNELS * i], &qmf_real1[IXHEAACE_QMF_CHANNELS * i], + memcpy_sz); + memcpy(&qmf_imag[IXHEAACE_QMF_CHANNELS * i], &qmf_imag1[IXHEAACE_QMF_CHANNELS * i], + memcpy_sz); + } + + for (i = 0; i < num_sample; i++) { + j = 0; + subsample_power_low[i] = 0.0f; + while (j < sub_band_start) { + subsample_power_low[i] += + qmf_real[IXHEAACE_QMF_CHANNELS * i + j] * qmf_real[IXHEAACE_QMF_CHANNELS * i + j]; + subsample_power_low[i] += + qmf_imag[IXHEAACE_QMF_CHANNELS * i + j] * qmf_imag[IXHEAACE_QMF_CHANNELS * i + j]; + j++; + } + subsample_power_high[i] = 0.0f; + while (j < sub_band_end) { + subsample_power_high[i] += + qmf_real[IXHEAACE_QMF_CHANNELS * i + j] * qmf_real[IXHEAACE_QMF_CHANNELS * i + j]; + subsample_power_high[i] += + qmf_imag[IXHEAACE_QMF_CHANNELS * i + j] * qmf_imag[IXHEAACE_QMF_CHANNELS * i + j]; + j++; + } + total_power_low += subsample_power_low[i]; + total_power_high += subsample_power_high[i]; + } + + for (i = 0; i < num_sample; i++) { + gain[i] = + (FLOAT32)(sqrt(subsample_power_low[i] * num_sample / (total_power_low + 1.0e-6f))); + gain[i] = (FLOAT32)(1.0f + gamma * (gain[i] - 1.0f)); + + if (gain[i] < 0.2f) { + gain[i] = 0.2f; + } + + subsample_power_high[i] *= gain[i] * gain[i]; + total_power_high_after += subsample_power_high[i]; + } + + gain_adj_2 = total_power_high / total_power_high_after; + gain_adj = (FLOAT32)(sqrt(gain_adj_2)); + + for (i = 0; i < num_sample; i++) { + gain[i] *= gain_adj; + + j = sub_band_start; + while (j < sub_band_end) { + qmf_real[IXHEAACE_QMF_CHANNELS * i + j] *= gain[i]; + qmf_imag[IXHEAACE_QMF_CHANNELS * i + j] *= gain[i]; + j++; + } + } + } +} + +static WORD32 ixheaace_inter_tes_sound_activity(FLOAT32 qmf_real[][IXHEAACE_QMF_CHANNELS], + FLOAT32 qmf_imag[][IXHEAACE_QMF_CHANNELS], + FLOAT32 energy[], WORD32 len, WORD32 start, + WORD32 stop, WORD32 *is_transient) { + WORD32 snd_act = 0, ts, idx; + FLOAT32 ene_min = MAX_FLT_VAL, ene_max = 0.0f; + + for (ts = 0; ts < len; ts++) { + idx = start; + while (idx < stop) { + energy[ts] += (qmf_real[ts][idx] * qmf_real[ts][idx]); + energy[ts] += (qmf_imag[ts][idx] * qmf_imag[ts][idx]); + idx++; + } + + if (energy[ts] > ene_max) { + ene_max = energy[ts]; + } + if (energy[ts] < ene_min) { + ene_min = energy[ts]; + } + } + + snd_act = (ene_max > IXHEAACE_ESBR_TES_ENERGY_MAX_THR) ? 1 : 0; + + if ((ene_max / (ene_min + 1.0e-6f)) > 20) { + *is_transient = 1; + } else { + *is_transient = 0; + } + return snd_act; +} + +static WORD16 ixheaace_find_closest_entry(WORD32 goal_sb, WORD16 *ptr_master_tab, + WORD16 num_mf_bands, WORD16 direction) { + WORD32 index; + + if (goal_sb <= ptr_master_tab[0]) return ptr_master_tab[0]; + + if (goal_sb >= ptr_master_tab[num_mf_bands]) return ptr_master_tab[num_mf_bands]; + + if (direction) { + index = 0; + while (ptr_master_tab[index] < goal_sb) { + index++; + } + } else { + index = num_mf_bands; + while (ptr_master_tab[index] > goal_sb) { + index--; + } + } + + return ptr_master_tab[index]; +} + +static VOID ixheaace_esbr_calc_co_variance(ixheaace_str_auto_corr_ele *pstr_auto_corr, + FLOAT32 ptr_vec_x_real[][IXHEAACE_QMF_CHANNELS], + FLOAT32 ptr_vec_x_imag[][IXHEAACE_QMF_CHANNELS], + WORD32 bd, WORD32 len) { + WORD32 j = 0; + + FLOAT32 xr_j; + FLOAT32 xr_j_minus_1 = ptr_vec_x_real[j - 1][bd]; + FLOAT32 xr_j_minus_2 = ptr_vec_x_real[j - 2][bd]; + + FLOAT32 xi_j; + FLOAT32 xi_j_minus_1 = ptr_vec_x_imag[j - 1][bd]; + FLOAT32 xi_j_minus_2 = ptr_vec_x_imag[j - 2][bd]; + + memset(pstr_auto_corr, 0, sizeof(ixheaace_str_auto_corr_ele)); + + for (j = 0; j < len; j++) { + xr_j = ptr_vec_x_real[j][bd]; + xi_j = ptr_vec_x_imag[j][bd]; + + pstr_auto_corr->phi_0_1_real += xr_j * xr_j_minus_1 + xi_j * xi_j_minus_1; + + pstr_auto_corr->phi_0_1_imag += xi_j * xr_j_minus_1 - xr_j * xi_j_minus_1; + + pstr_auto_corr->phi_0_2_real += xr_j * xr_j_minus_2 + xi_j * xi_j_minus_2; + + pstr_auto_corr->phi_0_2_imag += xi_j * xr_j_minus_2 - xr_j * xi_j_minus_2; + + pstr_auto_corr->phi_1_1 += xr_j_minus_1 * xr_j_minus_1 + xi_j_minus_1 * xi_j_minus_1; + + pstr_auto_corr->phi_1_2_real += xr_j_minus_1 * xr_j_minus_2 + xi_j_minus_1 * xi_j_minus_2; + + pstr_auto_corr->phi_1_2_imag += xi_j_minus_1 * xr_j_minus_2 - xr_j_minus_1 * xi_j_minus_2; + + pstr_auto_corr->phi_2_2 += xr_j_minus_2 * xr_j_minus_2 + xi_j_minus_2 * xi_j_minus_2; + + xr_j_minus_2 = xr_j_minus_1; + xr_j_minus_1 = xr_j; + + xi_j_minus_2 = xi_j_minus_1; + xi_j_minus_1 = xi_j; + } + + pstr_auto_corr->det = pstr_auto_corr->phi_1_1 * pstr_auto_corr->phi_2_2 - + (pstr_auto_corr->phi_1_2_real * pstr_auto_corr->phi_1_2_real + + pstr_auto_corr->phi_1_2_imag * pstr_auto_corr->phi_1_2_imag) * + IXHEAACE_SBR_HF_RELAXATION_PARAM; +} + +static VOID ixheaace_gausssolve(WORD32 n, FLOAT32 ptr_a[][IXHEAACE_MAXDEG + 1], FLOAT32 ptr_b[], + FLOAT32 ptr_y[]) { + WORD32 i, j, k, imax; + FLOAT32 v; + + for (i = 0; i < n; i++) { + imax = i; + k = i + 1; + while (k < n) { + if (fabs(ptr_a[k][i]) > fabs(ptr_a[imax][i])) { + imax = k; + } + k++; + } + if (imax != i) { + v = ptr_b[imax]; + ptr_b[imax] = ptr_b[i]; + ptr_b[i] = v; + j = i; + while (j < n) { + v = ptr_a[imax][j]; + ptr_a[imax][j] = ptr_a[i][j]; + ptr_a[i][j] = v; + j++; + } + } + + v = ptr_a[i][i]; + + ptr_b[i] /= v; + for (j = i; j < n; j++) { + ptr_a[i][j] /= v; + } + + for (k = i + 1; k < n; k++) { + v = ptr_a[k][i]; + ptr_b[k] -= v * ptr_b[i]; + for (j = i + 1; j < n; j++) { + ptr_a[k][j] -= v * ptr_a[i][j]; + } + } + } + + for (i = n - 1; i >= 0; i--) { + ptr_y[i] = ptr_b[i]; + for (j = i + 1; j < n; j++) { + ptr_y[i] -= ptr_a[i][j] * ptr_y[j]; + } + } +} + +static VOID ixheaace_polyfit(WORD32 n, FLOAT32 ptr_y[], FLOAT32 ptr_p[]) { + WORD32 i, j, k; + FLOAT32 ptr_a[IXHEAACE_MAXDEG + 1][IXHEAACE_MAXDEG + 1] = {{0}}; + FLOAT32 ptr_b[IXHEAACE_MAXDEG + 1] = {0}; + FLOAT32 v[2 * IXHEAACE_MAXDEG + 1]; + + for (k = 0; k < n; k++) { + v[0] = 1.0; + for (i = 1; i <= 2 * IXHEAACE_MAXDEG; i++) { + v[i] = k * v[i - 1]; + } + + for (i = 0; i <= IXHEAACE_MAXDEG; i++) { + ptr_b[i] += v[IXHEAACE_MAXDEG - i] * ptr_y[k]; + for (j = 0; j <= IXHEAACE_MAXDEG; j++) { + ptr_a[i][j] += v[2 * IXHEAACE_MAXDEG - i - j]; + } + } + } + + ixheaace_gausssolve(IXHEAACE_MAXDEG + 1, ptr_a, ptr_b, ptr_p); +} + +static VOID ixheaace_esbr_chirp_fac_calc(WORD32 *ptr_inv_filt_mode, + WORD32 *ptr_inv_filt_mode_prev, WORD32 num_if_bands, + FLOAT32 *ptr_bw_array, FLOAT32 *ptr_bw_array_prev) { + WORD32 i; + + for (i = 0; i < num_if_bands; i++) { + ptr_bw_array[i] = ixheaace_new_bw_tab[ptr_inv_filt_mode_prev[i]][ptr_inv_filt_mode[i]]; + + if (ptr_bw_array[i] < ptr_bw_array_prev[i]) { + ptr_bw_array[i] = 0.75000f * ptr_bw_array[i] + 0.25000f * ptr_bw_array_prev[i]; + } else { + ptr_bw_array[i] = 0.90625f * ptr_bw_array[i] + 0.09375f * ptr_bw_array_prev[i]; + } + + if (ptr_bw_array[i] < 0.015625) { + ptr_bw_array[i] = 0; + } + } +} + +static VOID ixheaace_pre_processing(FLOAT32 ptr_src_buf_real[][IXHEAACE_QMF_CHANNELS], + FLOAT32 ptr_src_buf_imag[][IXHEAACE_QMF_CHANNELS], + FLOAT32 ptr_gain_vector[], WORD32 num_bands, + WORD32 start_sample, WORD32 end_sample) { + WORD32 k, i; + FLOAT32 poly_coeff[4]; + FLOAT32 mean_enrg = 0; + FLOAT32 low_env_slope[IXHEAACE_QMF_CHANNELS]; + FLOAT32 low_env[IXHEAACE_QMF_CHANNELS]; + FLOAT32 a0; + FLOAT32 a1; + FLOAT32 a2; + FLOAT32 a3; + + for (k = 0; k < num_bands; k++) { + FLOAT32 temp = 0; + for (i = start_sample; i < end_sample; i++) { + temp += ptr_src_buf_real[i][k] * ptr_src_buf_real[i][k] + + ptr_src_buf_imag[i][k] * ptr_src_buf_imag[i][k]; + } + temp /= (end_sample - start_sample); + low_env[k] = (FLOAT32)(10 * log10(temp + 1)); + mean_enrg += low_env[k]; + } + mean_enrg /= num_bands; + + ixheaace_polyfit(num_bands, low_env, poly_coeff); + + a0 = poly_coeff[0]; + a1 = poly_coeff[1]; + a2 = poly_coeff[2]; + a3 = poly_coeff[3]; + for (k = 0; k < num_bands; k++) { + low_env_slope[k] = a3 + a2 * k + a1 * k * k + a0 * k * k * k; + } + + for (i = 0; i < num_bands; i++) { + ptr_gain_vector[i] = (FLOAT32)pow(10, (mean_enrg - low_env_slope[i]) / 20.0f); + } +} + +static IA_ERRORCODE ixheaace_generate_hf(FLOAT32 ptr_src_buf_real[][64], + FLOAT32 ptr_src_buf_imag[][64], + FLOAT32 ptr_ph_vocod_buf_real[][64], + FLOAT32 ptr_ph_vocod_buf_imag[][64], + FLOAT32 ptr_dst_buf_real[][64], + FLOAT32 ptr_dst_buf_imag[][64], + ixheaace_str_inter_tes_params *pstr_tes_enc) { + WORD32 bw_index, i, k, k2, patch = 0; + WORD32 co_var_len; + WORD32 start_sample, end_sample, goal_sb; + WORD32 sb, source_start_band, patch_stride, num_bands_in_patch; + WORD32 hbe_flag = 0; + FLOAT32 a0r, a0i, a1r, a1i; + FLOAT32 ptr_bw_array[IXHEAACE_MAX_NUM_PATCHES] = {0}; + + ixheaace_str_auto_corr_ele str_auto_corr; + + WORD16 *ptr_invf_band_tbl = &pstr_tes_enc->invf_band_tbl[1]; + WORD32 num_if_bands = pstr_tes_enc->num_if_bands; + WORD32 sub_band_start = pstr_tes_enc->sub_band_start; + WORD16 *ptr_master_tab = pstr_tes_enc->f_master_tbl; + WORD32 num_mf_bands = pstr_tes_enc->num_mf_bands; + WORD32 *ptr_inv_filt_mode = pstr_tes_enc->inv_filt_mode; + WORD32 *ptr_inv_filt_mode_prev = pstr_tes_enc->inv_filt_mode_prev; + WORD32 sbr_patching_mode = 1; + WORD32 pre_proc_flag = 0; + WORD32 fs = pstr_tes_enc->out_fs; + WORD32 cov_count; + WORD32 lsb = ptr_master_tab[0]; + WORD32 usb = ptr_master_tab[num_mf_bands]; + WORD32 memset_sz = (IXHEAACE_QMF_CHANNELS - usb) * sizeof(FLOAT32); + WORD32 xover_offset = sub_band_start - ptr_master_tab[0]; + FLOAT32 bw = 0.0f; + FLOAT32 fac = 0.0f; + FLOAT32 gain; + FLOAT32 ptr_gain_vector[64]; + WORD32 slope_length = 0; + WORD32 first_slot_offset = pstr_tes_enc->border_vec[0]; + WORD32 end_slot_offs = 0; + FLOAT32 *ptr_bw_array_prev = pstr_tes_enc->bw_array_prev; + + end_slot_offs = pstr_tes_enc->border_vec[pstr_tes_enc->num_env] - 16; + + switch (pstr_tes_enc->sbr_ratio_index) { + case USAC_SBR_RATIO_INDEX_2_1: + start_sample = first_slot_offset * 2; + end_sample = 32 + end_slot_offs * 2; + co_var_len = 38; + break; + case USAC_SBR_RATIO_INDEX_4_1: + start_sample = first_slot_offset * 4; + end_sample = 64 + end_slot_offs * 4; + co_var_len = 76; + break; + default: + start_sample = first_slot_offset * 2; + end_sample = 32 + end_slot_offs * 2; + co_var_len = 38; + break; + } + + if (pre_proc_flag) { + ixheaace_pre_processing(ptr_src_buf_real, ptr_src_buf_imag, ptr_gain_vector, + ptr_master_tab[0], start_sample, end_sample); + } + + ixheaace_esbr_chirp_fac_calc(ptr_inv_filt_mode, ptr_inv_filt_mode_prev, num_if_bands, + ptr_bw_array, ptr_bw_array_prev); + + for (i = start_sample; i < end_sample; i++) { + memset(ptr_dst_buf_real[i] + usb, 0, memset_sz); + memset(ptr_dst_buf_imag[i] + usb, 0, memset_sz); + } + + if (sbr_patching_mode || !hbe_flag) { + FLOAT32 alpha_real[IXHEAACE_QMF_CHANNELS][2] = {{0}}, + alpha_imag[IXHEAACE_QMF_CHANNELS][2] = {{0}}; + cov_count = ptr_master_tab[0]; + + for (k = 1; k < cov_count; k++) { + ixheaace_esbr_calc_co_variance(&str_auto_corr, &ptr_src_buf_real[0], &ptr_src_buf_imag[0], + k, co_var_len); + if (str_auto_corr.det == 0.0f) { + alpha_real[k][1] = alpha_imag[k][1] = 0; + } else { + fac = 1.0f / str_auto_corr.det; + alpha_real[k][1] = (str_auto_corr.phi_0_1_real * str_auto_corr.phi_1_2_real - + str_auto_corr.phi_0_1_imag * str_auto_corr.phi_1_2_imag - + str_auto_corr.phi_0_2_real * str_auto_corr.phi_1_1) * + fac; + alpha_imag[k][1] = (str_auto_corr.phi_0_1_imag * str_auto_corr.phi_1_2_real + + str_auto_corr.phi_0_1_real * str_auto_corr.phi_1_2_imag - + str_auto_corr.phi_0_2_imag * str_auto_corr.phi_1_1) * + fac; + } + + if (str_auto_corr.phi_1_1 == 0) { + alpha_real[k][0] = alpha_imag[k][0] = 0; + } else { + fac = 1.0f / str_auto_corr.phi_1_1; + alpha_real[k][0] = + -(str_auto_corr.phi_0_1_real + alpha_real[k][1] * str_auto_corr.phi_1_2_real + + alpha_imag[k][1] * str_auto_corr.phi_1_2_imag) * + fac; + alpha_imag[k][0] = + -(str_auto_corr.phi_0_1_imag + alpha_imag[k][1] * str_auto_corr.phi_1_2_real - + alpha_real[k][1] * str_auto_corr.phi_1_2_imag) * + fac; + } + + if ((alpha_real[k][0] * alpha_real[k][0] + alpha_imag[k][0] * alpha_imag[k][0] >= 16.0f) || + (alpha_real[k][1] * alpha_real[k][1] + alpha_imag[k][1] * alpha_imag[k][1] >= 16.0f)) { + alpha_real[k][0] = 0.0f; + alpha_imag[k][0] = 0.0f; + alpha_real[k][1] = 0.0f; + alpha_imag[k][1] = 0.0f; + } + } + + goal_sb = (WORD32)(2.048e6f / fs + 0.5f); + { + WORD32 index; + if (goal_sb < ptr_master_tab[num_mf_bands]) { + for (index = 0; (ptr_master_tab[index] < goal_sb); index++) + goal_sb = ptr_master_tab[index]; + } else { + goal_sb = ptr_master_tab[num_mf_bands]; + } + } + + source_start_band = xover_offset + 1; + + sb = lsb + xover_offset; + + patch = 0; + while (sb < usb) { + if (IXHEAACE_MAX_NUM_PATCHES <= patch) { + return IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_NUM_PATCH; + } + + num_bands_in_patch = goal_sb - sb; + + if (num_bands_in_patch + source_start_band >= lsb) { + patch_stride = sb - source_start_band; + patch_stride = patch_stride & ~1; + num_bands_in_patch = lsb - (sb - patch_stride); + num_bands_in_patch = ixheaace_find_closest_entry(sb + num_bands_in_patch, ptr_master_tab, + (WORD16)(num_mf_bands), 0) - + (WORD32)(sb); + } + + patch_stride = num_bands_in_patch + sb - lsb; + patch_stride = (patch_stride + 1) & ~1; + + source_start_band = 1; + + if (goal_sb - (sb + num_bands_in_patch) < 3) { + goal_sb = usb; + } + + if ((num_bands_in_patch < 3) && (patch > 0) && (sb + num_bands_in_patch == usb)) { + for (i = start_sample + slope_length; i < end_sample + slope_length; i++) { + for (k2 = sb; k2 < sb + num_bands_in_patch; k2++) { + if (k2 < 0 || k2 >= 64) { + break; + } + ptr_dst_buf_real[i][k2] = 0.0f; + ptr_dst_buf_imag[i][k2] = 0.0f; + } + } + break; + } + + if (num_bands_in_patch <= 0) { + continue; + } + + for (k2 = sb; k2 < sb + num_bands_in_patch; k2++) { + k = k2 - patch_stride; + bw_index = 0; + while (k2 >= ptr_invf_band_tbl[bw_index]) { + bw_index++; + if (bw_index >= IXHEAACE_MAX_NOISE_COEFFS) { + return IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_BANDWIDTH_INDEX; + } + } + + if (bw_index >= IXHEAACE_MAX_NUM_PATCHES) { + return IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_BANDWIDTH_INDEX; + } + bw = ptr_bw_array[bw_index]; + + a0r = bw * alpha_real[k][0]; + a0i = bw * alpha_imag[k][0]; + bw *= bw; + a1r = bw * alpha_real[k][1]; + a1i = bw * alpha_imag[k][1]; + + if (pre_proc_flag) { + gain = ptr_gain_vector[k]; + } else { + gain = 1.0f; + } + + for (i = start_sample + slope_length; i < end_sample + slope_length; i++) { + ptr_dst_buf_real[i][k2] = ptr_src_buf_real[i][k] * gain; + + ptr_dst_buf_imag[i][k2] = ptr_src_buf_imag[i][k] * gain; + + if (bw > 0.0f) { + ptr_dst_buf_real[i][k2] += + (a0r * ptr_src_buf_real[i - 1][k] - a0i * ptr_src_buf_imag[i - 1][k] + + a1r * ptr_src_buf_real[i - 2][k] - a1i * ptr_src_buf_imag[i - 2][k]) * + gain; + ptr_dst_buf_imag[i][k2] += + (a0i * ptr_src_buf_real[i - 1][k] + a0r * ptr_src_buf_imag[i - 1][k] + + a1i * ptr_src_buf_real[i - 2][k] + a1r * ptr_src_buf_imag[i - 2][k]) * + gain; + } + } + } + sb += num_bands_in_patch; + patch++; + } + } + + if (hbe_flag && !sbr_patching_mode) { + FLOAT32 alpha_real[2], alpha_imag[2]; + + bw_index = 0, patch = 1; + if (NULL == ptr_ph_vocod_buf_real || NULL == ptr_ph_vocod_buf_imag) { + return IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_VOCOD_BUF; + } + + for (k2 = sub_band_start; k2 < ptr_master_tab[num_mf_bands]; k2++) { + ixheaace_esbr_calc_co_variance(&str_auto_corr, &ptr_ph_vocod_buf_real[0], + &ptr_ph_vocod_buf_imag[0], k2, co_var_len); + + if (str_auto_corr.det == 0.0f) { + alpha_real[1] = alpha_imag[1] = 0; + } else { + fac = 1.0f / str_auto_corr.det; + alpha_real[1] = (str_auto_corr.phi_0_1_real * str_auto_corr.phi_1_2_real - + str_auto_corr.phi_0_1_imag * str_auto_corr.phi_1_2_imag - + str_auto_corr.phi_0_2_real * str_auto_corr.phi_1_1) * + fac; + alpha_imag[1] = (str_auto_corr.phi_0_1_imag * str_auto_corr.phi_1_2_real + + str_auto_corr.phi_0_1_real * str_auto_corr.phi_1_2_imag - + str_auto_corr.phi_0_2_imag * str_auto_corr.phi_1_1) * + fac; + } + + if (str_auto_corr.phi_1_1 == 0) { + alpha_real[0] = alpha_imag[0] = 0; + } else { + fac = 1.0f / str_auto_corr.phi_1_1; + alpha_real[0] = + -(str_auto_corr.phi_0_1_real + alpha_real[1] * str_auto_corr.phi_1_2_real + + alpha_imag[1] * str_auto_corr.phi_1_2_imag) * + fac; + alpha_imag[0] = + -(str_auto_corr.phi_0_1_imag + alpha_imag[1] * str_auto_corr.phi_1_2_real - + alpha_real[1] * str_auto_corr.phi_1_2_imag) * + fac; + } + + if (alpha_real[0] * alpha_real[0] + alpha_imag[0] * alpha_imag[0] >= 16.0f || + alpha_real[1] * alpha_real[1] + alpha_imag[1] * alpha_imag[1] >= 16.0f) { + alpha_real[0] = 0.0f; + alpha_imag[0] = 0.0f; + alpha_real[1] = 0.0f; + alpha_imag[1] = 0.0f; + } + + while (k2 >= ptr_invf_band_tbl[bw_index]) { + bw_index++; + if (bw_index >= IXHEAACE_MAX_NOISE_COEFFS) { + return IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_BANDWIDTH_INDEX; + } + } + + if (bw_index >= IXHEAACE_MAX_NUM_PATCHES) { + return IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_BANDWIDTH_INDEX; + } + bw = ptr_bw_array[bw_index]; + + a0r = bw * alpha_real[0]; + a0i = bw * alpha_imag[0]; + bw *= bw; + a1r = bw * alpha_real[1]; + a1i = bw * alpha_imag[1]; + + if (bw > 0.0f) { + for (i = start_sample; i < end_sample; i++) { + FLOAT32 real1, imag1, real2, imag2; + + real1 = ptr_ph_vocod_buf_real[i - 1][k2]; + imag1 = ptr_ph_vocod_buf_imag[i - 1][k2]; + real2 = ptr_ph_vocod_buf_real[i - 2][k2]; + imag2 = ptr_ph_vocod_buf_imag[i - 2][k2]; + ptr_dst_buf_real[i][k2] = ptr_ph_vocod_buf_real[i][k2] + + ((a0r * real1 - a0i * imag1) + (a1r * real2 - a1i * imag2)); + ptr_dst_buf_imag[i][k2] = ptr_ph_vocod_buf_imag[i][k2] + + ((a0i * real1 + a0r * imag1) + (a1i * real2 + a1r * imag2)); + } + } else { + for (i = start_sample; i < end_sample; i++) { + ptr_dst_buf_real[i][k2] = ptr_ph_vocod_buf_real[i][k2]; + ptr_dst_buf_imag[i][k2] = ptr_ph_vocod_buf_imag[i][k2]; + } + } + } + } + if (patch >= (IXHEAACE_MAX_NUM_PATCHES + 1)) { + return IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_NUM_PATCH; + } + for (i = 0; i < num_if_bands; i++) { + ptr_bw_array_prev[i] = ptr_bw_array[i]; + } + return IA_NO_ERROR; +} + +IA_ERRORCODE ixheaace_process_inter_tes(ixheaace_str_inter_tes_params *pstr_tes_enc, + WORD8 *ptr_scr) { + WORD32 gi = 0, env, tes_enable = 0, ts, bd, start_ts, stop_ts; + WORD32 is_sound_activity[IXHEAACE_MAX_ENVELOPES] = {0}, + is_transient[IXHEAACE_MAX_ENVELOPES] = {0}; + WORD32 tes_shape_mode = 0; + WORD32 num_samples, num_bands; + WORD32 len; + IA_ERRORCODE status = IA_NO_ERROR; + FLOAT32 energy_high[64] = {0}; + FLOAT32 energy[64] = {0}; + FLOAT32 gamma[IXHEAACE_ESBR_NUM_GAMMA_IDXS] = {0}; + FLOAT32 gamma_min = MAX_FLT_VAL; + ixheaace_str_inter_tes_scr *tes_scr = (ixheaace_str_inter_tes_scr *)ptr_scr; + num_bands = pstr_tes_enc->sub_band_end - pstr_tes_enc->sub_band_start; + + for (env = 0; env < pstr_tes_enc->num_env; env++) { + tes_shape_mode = 0; + len = 2 * (pstr_tes_enc->border_vec[env + 1] - pstr_tes_enc->border_vec[env]); + is_sound_activity[env] = ixheaace_inter_tes_sound_activity( + &pstr_tes_enc + ->qmf_buf_real[IXHEAACE_SBR_HF_ADJ_OFFSET + 2 * pstr_tes_enc->border_vec[env]], + &pstr_tes_enc + ->qmf_buf_imag[IXHEAACE_SBR_HF_ADJ_OFFSET + 2 * pstr_tes_enc->border_vec[env]], + &energy_high[IXHEAACE_SBR_HF_ADJ_OFFSET + 2 * pstr_tes_enc->border_vec[env]], len, + pstr_tes_enc->sub_band_start, pstr_tes_enc->sub_band_end, &is_transient[env]); + if (1 == is_transient[env] && 1 == is_sound_activity[env]) { + tes_enable = 1; + } + } + + if (1 == tes_enable) { + status = ixheaace_generate_hf(&pstr_tes_enc->qmf_buf_real[IXHEAACE_SBR_HF_ADJ_OFFSET], + &pstr_tes_enc->qmf_buf_imag[IXHEAACE_SBR_HF_ADJ_OFFSET], NULL, + NULL, &tes_scr->dst_qmf_r[IXHEAACE_SBR_HF_ADJ_OFFSET], + &tes_scr->dst_qmf_i[IXHEAACE_SBR_HF_ADJ_OFFSET], pstr_tes_enc); + + if (status) { + return status; + } + for (env = 0; env < pstr_tes_enc->num_env; env++) { + if ((1 == is_sound_activity[env]) && (1 == is_transient[env])) { + num_samples = (pstr_tes_enc->border_vec[env + 1] - pstr_tes_enc->border_vec[env]) * 2; + start_ts = IXHEAACE_SBR_HF_ADJ_OFFSET + pstr_tes_enc->border_vec[env] * 2; + stop_ts = start_ts + num_samples; + + for (gi = 0; gi < IXHEAACE_ESBR_NUM_GAMMA_IDXS; gi++) { + ixheaace_apply_inter_tes( + &tes_scr + ->dst_qmf_r[IXHEAACE_SBR_HF_ADJ_OFFSET + 2 * pstr_tes_enc->border_vec[env]][0], + &tes_scr + ->dst_qmf_i[IXHEAACE_SBR_HF_ADJ_OFFSET + 2 * pstr_tes_enc->border_vec[env]][0], + &pstr_tes_enc->qmf_buf_real[IXHEAACE_SBR_HF_ADJ_OFFSET + + 2 * pstr_tes_enc->border_vec[env]][0], + &pstr_tes_enc->qmf_buf_imag[IXHEAACE_SBR_HF_ADJ_OFFSET + + 2 * pstr_tes_enc->border_vec[env]][0], + num_samples, pstr_tes_enc->sub_band_start, num_bands, gi); + for (ts = start_ts; ts < stop_ts; ts++) { + energy[ts] = 0.0f; + for (bd = pstr_tes_enc->sub_band_start; bd < pstr_tes_enc->sub_band_end; bd++) { + energy[ts] += tes_scr->dst_qmf_r[ts][bd] * tes_scr->dst_qmf_r[ts][bd]; + energy[ts] += tes_scr->dst_qmf_i[ts][bd] * tes_scr->dst_qmf_i[ts][bd]; + } + gamma[gi] += (FLOAT32)fabs(energy[ts] - energy_high[ts]) / + (FLOAT32)(pow((energy_high[ts] + 1e-6f), 0.9f)); + } + if (gamma[gi] < gamma_min) { + gamma_min = gamma[gi]; + tes_shape_mode = gi; + } + } + } + + if (tes_shape_mode > 0) { + pstr_tes_enc->bs_tes_shape[env] = 1; + pstr_tes_enc->bs_tes_shape_mode[env] = tes_shape_mode; + } else { + pstr_tes_enc->bs_tes_shape[env] = 0; + pstr_tes_enc->bs_tes_shape_mode[env] = 0; + } + } + } else { + for (env = 0; env < pstr_tes_enc->num_env; env++) { + pstr_tes_enc->bs_tes_shape[env] = 0; + pstr_tes_enc->bs_tes_shape_mode[env] = 0; + } + } + return status; +} diff --git a/encoder/iusace_esbr_inter_tes.h b/encoder/iusace_esbr_inter_tes.h new file mode 100644 index 0000000..9771cb3 --- /dev/null +++ b/encoder/iusace_esbr_inter_tes.h @@ -0,0 +1,115 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once + +#define IXHEAACE_ESBR_TES_ENERGY_MAX_THR (1.0e6f) +#define IXHEAACE_TIMESLOT_BUFFER_SIZE (78) +#define IXHEAACE_MAX_ENVELOPES (8) +#define IXHEAACE_MAX_NOISE_ENVELOPES (2) +#define IXHEAACE_MAX_NOISE_COEFFS (5) +#define IXHEAACE_MAX_NUM_NOISE_VALUES (IXHEAACE_MAX_NOISE_ENVELOPES * IXHEAACE_MAX_NOISE_COEFFS) +#define IXHEAACE_MAX_FREQ_COEFFS (56) +#define IXHEAACE_MAX_NUM_PATCHES (6) +#define IXHEAACE_MAX_NUM_LIMITERS (12) +#define IXHEAACE_MAXDEG (3) +#define IXHEAACE_SBR_HF_RELAXATION_PARAM (0.999999f) +#define IXHEAACE_ESBR_NUM_GAMMA_IDXS (4) +#define IXHEAACE_ESBR_HBE_DELAY_OFFSET (32) +#define IXHEAACE_SBR_HF_ADJ_OFFSET (2) +#define IXHEAACE_SBR_TES_SHAPE_BITS (1) +#define IXHEAACE_SBR_TES_SHAPE_MODE_BITS (2) + +typedef struct { + FLOAT32 phi_0_1_real; + FLOAT32 phi_0_1_imag; + FLOAT32 phi_0_2_real; + FLOAT32 phi_0_2_imag; + FLOAT32 phi_1_1; + FLOAT32 phi_1_2_real; + FLOAT32 phi_1_2_imag; + FLOAT32 phi_2_2; + FLOAT32 det; +} ixheaace_str_auto_corr_ele; + +typedef struct { + WORD16 num_sf_bands[2]; + WORD16 num_nf_bands; + WORD16 num_mf_bands; + WORD16 sub_band_start; + WORD16 sub_band_end; + WORD16 freq_band_tbl_lim[IXHEAACE_MAX_NUM_LIMITERS + 1]; + WORD16 num_lf_bands; + WORD16 num_if_bands; + WORD16 *ptr_freq_band_tab[2]; + WORD16 freq_band_tbl_lo[IXHEAACE_MAX_FREQ_COEFFS / 2 + 1]; + WORD16 freq_band_tbl_hi[IXHEAACE_MAX_FREQ_COEFFS + 1]; + WORD16 freq_band_tbl_noise[IXHEAACE_MAX_NOISE_COEFFS + 1]; + WORD16 f_master_tbl[IXHEAACE_MAX_FREQ_COEFFS + 1]; + WORD16 qmf_sb_prev; +} ia_str_freq_band_data; + +typedef struct { + WORD16 frame_class; + WORD16 num_env; + WORD16 transient_env; + WORD16 num_noise_env; + WORD16 border_vec[IXHEAACE_MAX_ENVELOPES + 1]; + WORD16 freq_res[IXHEAACE_MAX_ENVELOPES]; + WORD16 noise_border_vec[IXHEAACE_MAX_NOISE_ENVELOPES + 1]; +} ia_str_frame_info; + +typedef struct { + WORD32 num_if_bands; + WORD32 sub_band_start; + WORD32 sub_band_end; + WORD32 num_mf_bands; + WORD32 sbr_patching_mode; + WORD32 pre_proc_flag; + WORD32 is_usf_4; + WORD32 hbe_flag; + WORD32 out_fs; + WORD32 num_env; + WORD32 op_delay; + WORD32 codec_delay; + WORD32 sbr_ratio_index; + WORD16 invf_band_tbl[MAXIMUM_NUM_NOISE_VALUES + 1]; + WORD16 f_master_tbl[MAXIMUM_FREQ_COEFFS + 1]; + WORD32 inv_filt_mode[MAXIMUM_NUM_NOISE_VALUES]; + WORD32 inv_filt_mode_prev[IXHEAACE_MAX_NUM_NOISE_VALUES]; + FLOAT32 bw_array_prev[IXHEAACE_MAX_NUM_PATCHES]; + WORD16 border_vec[IXHEAACE_MAX_ENV + 1]; + WORD32 bs_tes_shape[IXHEAACE_MAX_ENV + 1]; + WORD32 bs_tes_shape_mode[IXHEAACE_MAX_ENV + 1]; + FLOAT32 qmf_buf_real[IXHEAACE_TIMESLOT_BUFFER_SIZE + 2 * IXHEAACE_ESBR_HBE_DELAY_OFFSET] + [IXHEAACE_QMF_CHANNELS]; + FLOAT32 qmf_buf_imag[IXHEAACE_TIMESLOT_BUFFER_SIZE + 2 * IXHEAACE_ESBR_HBE_DELAY_OFFSET] + [IXHEAACE_QMF_CHANNELS]; +} ixheaace_str_inter_tes_params; + +typedef struct { + FLOAT32 dst_qmf_r[IXHEAACE_TIMESLOT_BUFFER_SIZE][IXHEAACE_QMF_CHANNELS]; + FLOAT32 dst_qmf_i[IXHEAACE_TIMESLOT_BUFFER_SIZE][IXHEAACE_QMF_CHANNELS]; +} ixheaace_str_inter_tes_scr; + +VOID ixheaace_init_esbr_inter_tes(ixheaace_str_inter_tes_params *pstr_tes_enc, + WORD32 sbr_ratio_index); +IA_ERRORCODE ixheaace_process_inter_tes(ixheaace_str_inter_tes_params *pstr_tes_enc, + WORD8 *ptr_scr); diff --git a/encoder/iusace_esbr_pvc.c b/encoder/iusace_esbr_pvc.c new file mode 100644 index 0000000..a502ab7 --- /dev/null +++ b/encoder/iusace_esbr_pvc.c @@ -0,0 +1,426 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include + +#include "ixheaac_type_def.h" +#include "ixheaac_constants.h" +#include "ixheaace_aac_constants.h" +#include "ixheaac_basic_ops32.h" +#include "ixheaac_basic_ops16.h" +#include "ixheaac_basic_ops40.h" +#include "ixheaac_error_standards.h" +#include "ixheaace_error_codes.h" + +#include "ixheaace_bitbuffer.h" +#include "iusace_esbr_pvc.h" +#include "ixheaace_common_utils.h" +#include "ixheaace_sbr_cmondata.h" + +IA_ERRORCODE ixheaace_pvc_enc_init(ixheaace_pvc_enc *pstr_pvc_enc, WORD32 sbr_pvc_rate) { + pstr_pvc_enc->pvc_prv_param.pvc_flag = IXHEAACE_ESBR_PVC_FLAG_PREV_DFLT; + pstr_pvc_enc->pvc_prv_param.pvc_id = IXHEAACE_ESBR_PVC_ID_PREV_DFLT; + pstr_pvc_enc->pvc_prv_param.pvc_rate = IXHEAACE_ESBR_PVC_RATE_PREV_DFLT; + pstr_pvc_enc->pvc_prv_param.start_band = IXHEAACE_ESBR_PVC_STRT_BAND_PREV_DFLT; + pstr_pvc_enc->pvc_param.pvc_rate = (UWORD8)sbr_pvc_rate; + + return IA_NO_ERROR; +} + +static VOID ixheaace_pvc_sb_grouping(ixheaace_pvc_enc *pstr_pvc_enc, UWORD8 start_band, + FLOAT32 *ptr_qmf_low, FLOAT32 *ptr_sb_grp_energy, + WORD32 first_pvc_ts) { + WORD32 ksg, ts, band; + FLOAT32 tmp_sb_grp_energy; + WORD32 lbw, sb; + WORD32 nqmf_lb; + FLOAT32 *ptr_tmp_qmfl; + + ixheaace_pvc_params *pstr_params = &pstr_pvc_enc->pvc_param; + ixheaace_pvc_prv_frm_params *pstr_prv_params = &pstr_pvc_enc->pvc_prv_param; + + nqmf_lb = IXHEAACE_ESBR_PVC_NUM_QMF_BANDS / pstr_params->pvc_rate; + lbw = 8 / pstr_params->pvc_rate; + + for (ts = 0; ts < IXHEAACE_ESBR_PVC_NUM_TS; ts++) { + sb = start_band - lbw * pstr_params->num_grp_core; + ksg = 0; + while (ksg < pstr_params->num_grp_core) { + tmp_sb_grp_energy = 0.0f; + if (sb >= 0) { + ptr_tmp_qmfl = &ptr_qmf_low[ts * nqmf_lb + sb]; + band = 0; + while (band < lbw) { + tmp_sb_grp_energy += ptr_tmp_qmfl[band]; + band++; + } + tmp_sb_grp_energy /= lbw; + } + + tmp_sb_grp_energy = max(IXHEAACE_ESBR_PVC_POW_THRS, tmp_sb_grp_energy); + ptr_sb_grp_energy[(ts + IXHEAACE_ESBR_PVC_NUM_TS - 1) * 3 + ksg] = + 10 * (FLOAT32)log10(tmp_sb_grp_energy); + sb += lbw; + ksg++; + } + } + + if ((pstr_prv_params->pvc_flag == 0) || + ((start_band * pstr_params->pvc_rate) != + (pstr_prv_params->start_band * pstr_prv_params->pvc_rate))) { + for (ts = 0; ts < IXHEAACE_ESBR_PVC_NUM_TS - 1 + first_pvc_ts; ts++) { + memcpy(&ptr_sb_grp_energy[ts * 3], + &ptr_sb_grp_energy[(IXHEAACE_ESBR_PVC_NUM_TS - 1 + first_pvc_ts) * 3], + pstr_params->num_grp_core * sizeof(ptr_sb_grp_energy[0])); + } + } + + return; +} + +static IA_ERRORCODE ixheaace_set_pvc_mode_param(ixheaace_pvc_params *pstr_pvc_param, + ixheaace_pvc_coef_tabs *pstr_pvc_tabs) { + pstr_pvc_param->num_grp_core = IXHEAACE_ESBR_PVC_NUM_BANDS_CORE; + pstr_pvc_param->num_pvc_id = IXHEAACE_ESBR_PVC_NUM_PVCID; + + switch (pstr_pvc_param->pvc_mode) { + case IXHEAACE_ESBR_PVC_MODE_1: + pstr_pvc_param->num_grp_sbr = IXHEAACE_ESBR_PVC_NUM_BANDS_SBR_MODE1; + pstr_pvc_param->hbw = 8 / pstr_pvc_param->pvc_rate; + pstr_pvc_tabs->pvc_pred_coef_kb_012 = + (UWORD8 *)ixheaace_pvc_tabs.pvc_prd_coef_kb_012_mode_1; + pstr_pvc_tabs->pvc_pred_coef_kb_3 = (UWORD8 *)ixheaace_pvc_tabs.pvc_prd_coef_kb_3_mode_1; + pstr_pvc_tabs->pvc_idx_tab = ixheaace_pvc_tabs.pvc_idx_mode_1; + pstr_pvc_tabs->scaling_coef = ixheaace_pvc_tabs.pvc_scaling_coef_mode_1; + break; + + case IXHEAACE_ESBR_PVC_MODE_2: + pstr_pvc_param->num_grp_sbr = IXHEAACE_ESBR_PVC_NUM_BANDS_SBR_MODE2; + pstr_pvc_param->hbw = 12 / pstr_pvc_param->pvc_rate; + pstr_pvc_tabs->pvc_pred_coef_kb_012 = + (UWORD8 *)ixheaace_pvc_tabs.pvc_prd_coef_kb_012_mode_2; + pstr_pvc_tabs->pvc_pred_coef_kb_3 = (UWORD8 *)ixheaace_pvc_tabs.pvc_prd_coef_kb_3_mode_2; + pstr_pvc_tabs->pvc_idx_tab = ixheaace_pvc_tabs.pvc_idx_mode_2; + pstr_pvc_tabs->scaling_coef = ixheaace_pvc_tabs.pvc_scaling_coef_mode_2; + break; + + default: + return IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_PVC_MODE; + } + return IA_NO_ERROR; +} + +static VOID ixheaace_pvc_sb_grouping_ref(ixheaace_pvc_params *pstr_pvc_param, UWORD8 start_band, + UWORD8 stop_band, FLOAT32 *ptr_qmf_high, + FLOAT32 *ptr_sb_grp_energy) { + WORD32 ksg, ts, band; + UWORD8 min_sb; + WORD32 sb, eb; + FLOAT32 tmp_sb_grp_energy; + + min_sb = start_band + pstr_pvc_param->num_grp_sbr * pstr_pvc_param->hbw - 1; + stop_band = max(stop_band, min_sb); + + for (ts = 0; ts < IXHEAACE_ESBR_PVC_NUM_TS; ts++) { + sb = start_band; + eb = min((sb + pstr_pvc_param->hbw - 1), (IXHEAACE_ESBR_PVC_NUM_QMF_BANDS - 1)); + + for (ksg = 0; ksg < (pstr_pvc_param->num_grp_sbr - 2); ksg++) { + tmp_sb_grp_energy = 0.0f; + band = sb; + while (band <= eb) { + tmp_sb_grp_energy += ptr_qmf_high[ts * IXHEAACE_ESBR_PVC_NUM_QMF_BANDS + band]; + band++; + } + tmp_sb_grp_energy = tmp_sb_grp_energy / (eb - sb + 1); + + ptr_sb_grp_energy[ts * pstr_pvc_param->num_grp_sbr + ksg] = + max(IXHEAACE_ESBR_PVC_POW_THRS, tmp_sb_grp_energy); + sb += pstr_pvc_param->hbw; + eb = min((sb + pstr_pvc_param->hbw - 1), stop_band); + eb = min(eb, (IXHEAACE_ESBR_PVC_NUM_QMF_BANDS - 1)); + } + + while (ksg < pstr_pvc_param->num_grp_sbr) { + tmp_sb_grp_energy = 0.0f; + band = sb; + while (band <= eb) { + tmp_sb_grp_energy += ptr_qmf_high[ts * IXHEAACE_ESBR_PVC_NUM_QMF_BANDS + band]; + band++; + } + tmp_sb_grp_energy = tmp_sb_grp_energy / (eb - sb + 1); + + ptr_sb_grp_energy[ts * pstr_pvc_param->num_grp_sbr + ksg] = + max(IXHEAACE_ESBR_PVC_POW_THRS, tmp_sb_grp_energy); + sb += pstr_pvc_param->hbw; + eb = min(stop_band, (IXHEAACE_ESBR_PVC_NUM_QMF_BANDS - 1)); + ksg++; + } + } + return; +} + +static VOID ixheaace_pvc_calc_grp_energy_below_sbr(ixheaace_pvc_enc *pstr_pvc_enc, WORD32 ts, + FLOAT32 *ptr_sb_grp_ene_blsbr) { + WORD32 ksg = 0, idx; + ixheaace_pvc_params *pstr_pvc_params = &pstr_pvc_enc->pvc_param; + + memset(ptr_sb_grp_ene_blsbr, 0, + pstr_pvc_params->num_grp_core * sizeof(ptr_sb_grp_ene_blsbr[0])); + + while (ksg < pstr_pvc_params->num_grp_core) { + for (idx = 0; idx < pstr_pvc_params->time_smth_ts; idx++) { + ptr_sb_grp_ene_blsbr[ksg] += + pstr_pvc_enc->sb_grp_energy[ts + IXHEAACE_ESBR_PVC_NUM_TS - 1 - idx][ksg] * + pstr_pvc_enc->pvc_tabs.smoothing_coef[idx]; + } + ksg++; + } + return; +} + +static VOID ixheaace_pvc_predict(ixheaace_pvc_enc *pstr_pvc_enc, WORD32 ts, + FLOAT32 *ptr_sb_grp_ene_blsbr, FLOAT32 *ptr_sb_grp_energy_high) { + ixheaace_pvc_params *pstr_pvc_params = &(pstr_pvc_enc->pvc_param); + ixheaace_pvc_coef_tabs *pstr_pvc_tabs = &(pstr_pvc_enc->pvc_tabs); + + WORD32 ksg, kb, idx_tab_1, idx_tab_2; + const UWORD8 *ptr_tab; + FLOAT32 prod; + + idx_tab_2 = pstr_pvc_params->pvc_id[ts]; + + if (idx_tab_2 < pstr_pvc_tabs->pvc_idx_tab[0]) { + idx_tab_1 = 0; + } else if (idx_tab_2 < pstr_pvc_tabs->pvc_idx_tab[1]) { + idx_tab_1 = 1; + } else { + idx_tab_1 = 2; + } + + memset(ptr_sb_grp_energy_high, 0, + pstr_pvc_params->num_grp_sbr * sizeof(ptr_sb_grp_energy_high[0])); + + ptr_tab = &(pstr_pvc_tabs->pvc_pred_coef_kb_012[idx_tab_1 * pstr_pvc_params->num_grp_core * + pstr_pvc_params->num_grp_sbr]); + + for (kb = 0; kb < pstr_pvc_params->num_grp_core; kb++) { + prod = pstr_pvc_tabs->scaling_coef[kb] * ptr_sb_grp_ene_blsbr[kb]; + for (ksg = 0; ksg < pstr_pvc_params->num_grp_sbr; ksg++) { + ptr_sb_grp_energy_high[ksg] += ((FLOAT32)(WORD8)(*(ptr_tab++)) * prod); + } + } + + ptr_tab = &(pstr_pvc_tabs->pvc_pred_coef_kb_3[idx_tab_2 * pstr_pvc_params->num_grp_sbr]); + prod = pstr_pvc_tabs->scaling_coef[pstr_pvc_params->num_grp_core]; + + for (ksg = 0; ksg < pstr_pvc_params->num_grp_sbr; ksg++) { + ptr_sb_grp_energy_high[ksg] += (FLOAT32)(WORD8)(*(ptr_tab++)) * prod; + } + + return; +} + +static VOID ixheaace_pvc_packing(ixheaace_pvc_enc *pstr_pvc_enc, WORD32 const usac_indep_flag) { + UWORD16 *ptr_pvc_bs; + ixheaace_pvc_params *pstr_params = &pstr_pvc_enc->pvc_param; + ixheaace_pvc_prv_frm_params *pstr_prv_params = &pstr_pvc_enc->pvc_prv_param; + ixheaace_pvc_bs_info *pstr_pvc_bs_info = &pstr_pvc_enc->pvc_bs_info; + + ptr_pvc_bs = pstr_pvc_bs_info->pvc_id_bs; + + pstr_pvc_bs_info->ns_mode = pstr_params->ns_mode; + + if ((usac_indep_flag == 1) || (pstr_params->pvc_id[1] != pstr_prv_params->pvc_id)) { + pstr_pvc_bs_info->grid_info[0] = 1; + *(ptr_pvc_bs++) = pstr_params->pvc_id[0]; + } else { + pstr_pvc_bs_info->grid_info[0] = 0; + } + + if (pstr_params->pvc_id[8] == pstr_params->pvc_id[7]) { + pstr_pvc_bs_info->div_mode = 0; + } else { + pstr_pvc_bs_info->div_mode = 4; + pstr_pvc_bs_info->num_grid_info = 2; + pstr_pvc_bs_info->grid_info[1] = 1; + *(ptr_pvc_bs++) = pstr_params->pvc_id[8]; + } + return; +} + +static FLOAT32 ixheaace_pvc_calc_res(FLOAT32 *ptr_org, FLOAT32 *ptr_prd, UWORD8 ng_sb_sbr) { + FLOAT32 residual = 0, diff; + WORD32 band = 0; + + while (band < ng_sb_sbr) { + diff = ptr_org[band] - ptr_prd[band]; + residual += diff * diff; + band++; + } + residual = (FLOAT32)sqrt(residual); + + return residual; +} + +VOID ixheaace_pvc_calc_grp_energy(ixheaace_pvc_enc *pstr_pvc_enc, + FLOAT32 *ptr_sb_grp_energy_hi_ref) { + WORD32 ts, res_init_flg = 1, pvc_id, i; + FLOAT32 res_all[128] = {0}, res_min, sb_grp_energy_blwsbr[3], sb_grp_energy_hi[8], res = 0; + UWORD16 *ptr_pvc_id, tmp = 0; + + ptr_pvc_id = pstr_pvc_enc->pvc_param.pvc_id; + for (ts = 0; ts < IXHEAACE_ESBR_PVC_NUM_TS; ts++) { + ixheaace_pvc_calc_grp_energy_below_sbr(pstr_pvc_enc, ts, sb_grp_energy_blwsbr); + for (pvc_id = 0; pvc_id < pstr_pvc_enc->pvc_param.num_pvc_id; pvc_id++) { + pstr_pvc_enc->pvc_param.pvc_id[ts] = (UWORD16)pvc_id; + ixheaace_pvc_predict(pstr_pvc_enc, ts, sb_grp_energy_blwsbr, sb_grp_energy_hi); + + res = ixheaace_pvc_calc_res( + &(ptr_sb_grp_energy_hi_ref[ts * pstr_pvc_enc->pvc_param.num_grp_sbr]), sb_grp_energy_hi, + pstr_pvc_enc->pvc_param.num_grp_sbr); + if (res_init_flg) { + res_all[pvc_id] = res; + } else { + res_all[pvc_id] += res; + } + } + + res_init_flg = 0; + if ((ts & (IXHEAACE_ESBR_PVC_NTS_GRP_ID - 1)) == (IXHEAACE_ESBR_PVC_NTS_GRP_ID - 1)) { + res_min = IXHEAACE_ESBR_PVC_RESIDUAL_VAL; + pvc_id = 0; + while (pvc_id < pstr_pvc_enc->pvc_param.num_pvc_id) { + if (res_all[pvc_id] < res_min) { + tmp = (UWORD16)pvc_id; + res_min = res_all[pvc_id]; + } + pvc_id++; + } + for (i = 0; i < IXHEAACE_ESBR_PVC_NTS_GRP_ID; i++) { + *(ptr_pvc_id++) = tmp; + } + res_init_flg = 1; + } + } + + for (ts = 0; ts < 15; ts++) { + memcpy(&pstr_pvc_enc->sb_grp_energy[ts][0], + &pstr_pvc_enc->sb_grp_energy[ts + IXHEAACE_ESBR_PVC_NUM_TS][0], + IXHEAACE_ESBR_PVC_NUM_BANDS_CORE * sizeof(pstr_pvc_enc->sb_grp_energy[ts][0])); + } +} + +VOID ixheaace_pvc_calc_ref_ene_update_tabs(ixheaace_pvc_enc *pstr_pvc_enc, + FLOAT32 *ptr_sb_grp_energy_hi_ref) { + WORD32 ts, band; + FLOAT32 sum, prev_sum = 0; + pstr_pvc_enc->pvc_param.ns_mode = 0; + + switch (pstr_pvc_enc->pvc_param.pvc_mode) { + case 1: { + pstr_pvc_enc->pvc_param.time_smth_ts = IXHEAACE_ESBR_PVC_NUM_TS; + pstr_pvc_enc->pvc_tabs.smoothing_coef = ixheaace_pvc_tabs.pvc_smth_win_ns_16; + break; + } + case 2: { + pstr_pvc_enc->pvc_param.time_smth_ts = 12; + pstr_pvc_enc->pvc_tabs.smoothing_coef = ixheaace_pvc_tabs.pvc_smth_win_ns_12; + break; + } + default: { + // No assignment + break; + } + } + + for (ts = 0; ts < IXHEAACE_ESBR_PVC_NUM_TS; ts++) { + FLOAT32 *ptr_grp_energy = + &(ptr_sb_grp_energy_hi_ref[ts * pstr_pvc_enc->pvc_param.num_grp_sbr]); + sum = 0.0f; + for (band = 0; band < pstr_pvc_enc->pvc_param.num_grp_sbr; band++) { + sum += *ptr_grp_energy; + + *ptr_grp_energy = 10 * (FLOAT32)log10(*ptr_grp_energy); + ptr_grp_energy++; + } + if (ts && (sum > prev_sum * IXHEAACE_ESBR_PVC_NS_MODE_PRD_THRS)) { + pstr_pvc_enc->pvc_param.ns_mode = 1; + } + prev_sum = sum; + } + + if (pstr_pvc_enc->pvc_param.ns_mode == 1) { + switch (pstr_pvc_enc->pvc_param.pvc_mode) { + case 1: { + pstr_pvc_enc->pvc_param.time_smth_ts = 4; + pstr_pvc_enc->pvc_tabs.smoothing_coef = ixheaace_pvc_tabs.pvc_smth_win_ns_4; + break; + } + case 2: { + pstr_pvc_enc->pvc_param.time_smth_ts = 3; + pstr_pvc_enc->pvc_tabs.smoothing_coef = ixheaace_pvc_tabs.pvc_smth_win_ns_3; + break; + } + default: { + // No assignment + break; + } + } + } +} + +IA_ERRORCODE ixheaace_pvc_encode_frame(ixheaace_pvc_enc *pstr_pvc_enc, UWORD8 pvc_mode, + FLOAT32 *ptr_qmf_low, FLOAT32 *ptr_qmf_high, + UWORD8 start_band, UWORD8 stop_band) { + IA_ERRORCODE ret; + FLOAT32 sb_grp_energy_hi_ref[IXHEAACE_ESBR_PVC_NUM_TS * 8]; + + pstr_pvc_enc->pvc_param.pvc_mode = pvc_mode; + /* PVC encoding process */ + if (pstr_pvc_enc->pvc_param.pvc_mode) { + ret = ixheaace_set_pvc_mode_param(&(pstr_pvc_enc->pvc_param), &(pstr_pvc_enc->pvc_tabs)); + if (IA_NO_ERROR != ret) { + return ret; + } + + ixheaace_pvc_sb_grouping(pstr_pvc_enc, start_band, ptr_qmf_low, + (FLOAT32 *)pstr_pvc_enc->sb_grp_energy, 0); + + ixheaace_pvc_sb_grouping_ref(&(pstr_pvc_enc->pvc_param), start_band, stop_band, ptr_qmf_high, + sb_grp_energy_hi_ref); + ixheaace_pvc_calc_ref_ene_update_tabs(pstr_pvc_enc, sb_grp_energy_hi_ref); + + ixheaace_pvc_calc_grp_energy(pstr_pvc_enc, sb_grp_energy_hi_ref); + + ixheaace_pvc_packing(pstr_pvc_enc, pstr_pvc_enc->pvc_param.usac_indep_flag); + } + + pstr_pvc_enc->pvc_prv_param.pvc_id = + (pstr_pvc_enc->pvc_param.pvc_mode == 0) + ? 0xFF + : pstr_pvc_enc->pvc_param.pvc_id[IXHEAACE_ESBR_PVC_NUM_TS - 1]; + pstr_pvc_enc->pvc_prv_param.start_band = start_band; + pstr_pvc_enc->pvc_prv_param.pvc_flag = (pstr_pvc_enc->pvc_param.pvc_mode == 0) ? 0 : 1; + pstr_pvc_enc->pvc_prv_param.pvc_rate = pstr_pvc_enc->pvc_param.pvc_rate; + + return IA_NO_ERROR; +} diff --git a/encoder/iusace_esbr_pvc.h b/encoder/iusace_esbr_pvc.h new file mode 100644 index 0000000..43fc9de --- /dev/null +++ b/encoder/iusace_esbr_pvc.h @@ -0,0 +1,131 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +#define IXHEAACE_ESBR_PVC_MOD_NUM_TAB (2) +#define IXHEAACE_ESBR_PVC_NUM_TAB_IDX_1 (3) +#define IXHEAACE_ESBR_PVC_NUM_TAB_IDX_2 (128) +#define IXHEAACE_ESBR_PVC_NUM_PVCID (128) +#define IXHEAACE_ESBR_PVC_NUM_TS (16) +#define IXHEAACE_ESBR_PVC_NUM_QMF_BANDS (64) +#define IXHEAACE_ESBR_PVC_NUM_QMF_BANDS_CORE (64) +#define IXHEAACE_ESBR_PVC_NUM_BANDS_CORE (3) +#define IXHEAACE_ESBR_PVC_NUM_BANDS_SBR_MODE1 (8) +#define IXHEAACE_ESBR_PVC_NUM_BANDS_SBR_MODE2 (6) + +#define IXHEAACE_ESBR_PVC_POW_THRS (0.1f) +#define IXHEAACE_ESBR_PVC_NS_MODE_PRD_THRS (2) + +#define IXHEAACE_ESBR_PVC_RESIDUAL_VAL (1000000.0f) +#define IXHEAACE_ESBR_PVC_NTS_GRP_ID (8) + +#define IXHEAACE_ESBR_PVC_DIV_MODE_BITS (3) +#define IXHEAACE_ESBR_PVC_NS_MODE_BITS (1) +#define IXHEAACE_ESBR_PVC_ID_BITS (7) +#define IXHEAACE_ESBR_PVC_GRID_INFO_BITS (1) +#define IXHEAACE_ESBR_PVC_REUSE_BITS (1) + +#define IXHEAACE_ESBR_PVC_FLAG_PREV_DFLT (0) +#define IXHEAACE_ESBR_PVC_ID_PREV_DFLT (0xFF) +#define IXHEAACE_ESBR_PVC_RATE_PREV_DFLT (0xFF) +#define IXHEAACE_ESBR_PVC_STRT_BAND_PREV_DFLT (0xFF) + +#define IXHEAACE_ESBR_PVC_MODE_1 (1) +#define IXHEAACE_ESBR_PVC_MODE_2 (2) + +typedef struct { + const FLOAT32 pvc_smth_win_ns_16[16]; + const FLOAT32 pvc_smth_win_ns_12[12]; + const FLOAT32 pvc_smth_win_ns_4[4]; + const FLOAT32 pvc_smth_win_ns_3[3]; + const UWORD8 pvc_idx_mode_1[IXHEAACE_ESBR_PVC_MOD_NUM_TAB]; + const UWORD8 pvc_prd_coef_kb_3_mode_1[IXHEAACE_ESBR_PVC_NUM_TAB_IDX_2] + [IXHEAACE_ESBR_PVC_NUM_BANDS_SBR_MODE1]; + const UWORD8 pvc_prd_coef_kb_012_mode_1[IXHEAACE_ESBR_PVC_NUM_TAB_IDX_1] + [IXHEAACE_ESBR_PVC_NUM_BANDS_CORE] + [IXHEAACE_ESBR_PVC_NUM_BANDS_SBR_MODE1]; + const FLOAT32 pvc_scaling_coef_mode_1[IXHEAACE_ESBR_PVC_NUM_BANDS_CORE + 1]; + const UWORD8 pvc_idx_mode_2[IXHEAACE_ESBR_PVC_MOD_NUM_TAB]; + const UWORD8 pvc_prd_coef_kb_3_mode_2[IXHEAACE_ESBR_PVC_NUM_TAB_IDX_2] + [IXHEAACE_ESBR_PVC_NUM_BANDS_SBR_MODE2]; + const UWORD8 pvc_prd_coef_kb_012_mode_2[IXHEAACE_ESBR_PVC_NUM_TAB_IDX_1] + [IXHEAACE_ESBR_PVC_NUM_BANDS_CORE] + [IXHEAACE_ESBR_PVC_NUM_BANDS_SBR_MODE2]; + const FLOAT32 pvc_scaling_coef_mode_2[IXHEAACE_ESBR_PVC_NUM_BANDS_CORE + 1]; +} ixheaace_pvc_tabs_struct; + +extern const ixheaace_pvc_tabs_struct ixheaace_pvc_tabs; + +typedef struct { + UWORD8 pvc_mode; + UWORD8 div_mode; + UWORD8 ns_mode; + UWORD16 pvc_id[IXHEAACE_ESBR_PVC_NUM_TS]; + UWORD8 time_smth_ts; + UWORD8 num_grp_core; + UWORD8 num_grp_sbr; + UWORD8 hbw; + UWORD8 num_pvc_id; + UWORD8 pvc_rate; + WORD32 usac_indep_flag; +} ixheaace_pvc_params; + +typedef struct { + UWORD16 pvc_id; + UWORD8 start_band; + UWORD8 pvc_flag; + UWORD8 pvc_mode; + UWORD8 pvc_rate; +} ixheaace_pvc_prv_frm_params; + +typedef struct { + const FLOAT32 *smoothing_coef; + const FLOAT32 *scaling_coef; + const UWORD8 *pvc_pred_coef_kb_3; + const UWORD8 *pvc_pred_coef_kb_012; + const UWORD8 *pvc_idx_tab; +} ixheaace_pvc_coef_tabs; + +typedef struct { + UWORD8 div_mode; + UWORD8 grid_info[IXHEAACE_ESBR_PVC_NUM_TS]; + UWORD8 ns_mode; + WORD32 num_grid_info; + UWORD16 pvc_id_bs[IXHEAACE_ESBR_PVC_NUM_TS]; +} ixheaace_pvc_bs_info; + +typedef struct { + ixheaace_pvc_bs_info pvc_bs_info; + ixheaace_pvc_params pvc_param; + ixheaace_pvc_prv_frm_params pvc_prv_param; + ixheaace_pvc_coef_tabs pvc_tabs; + FLOAT32 sb_grp_energy[IXHEAACE_ESBR_PVC_NUM_TS + 16 - 1][3]; +} ixheaace_pvc_enc; + +typedef struct { + FLOAT32 pvc_qmf_low[IXHEAACE_ESBR_PVC_NUM_TS * IXHEAACE_ESBR_PVC_NUM_QMF_BANDS_CORE]; + FLOAT32 pvc_qmf_high[IXHEAACE_ESBR_PVC_NUM_TS * IXHEAACE_ESBR_PVC_NUM_QMF_BANDS]; +} ixheaace_pvc_scratch; + +IA_ERRORCODE ixheaace_pvc_enc_init(ixheaace_pvc_enc *pstr_pvc_enc, WORD32 sbr_pvc_rate); + +IA_ERRORCODE ixheaace_pvc_encode_frame(ixheaace_pvc_enc *pstr_pvc_enc, UWORD8 pvc_mode, + FLOAT32 *ptr_qmf_low, FLOAT32 *ptr_qmf_high, + UWORD8 start_band, UWORD8 stop_band); diff --git a/encoder/iusace_esbr_pvc_rom.c b/encoder/iusace_esbr_pvc_rom.c new file mode 100644 index 0000000..706041b --- /dev/null +++ b/encoder/iusace_esbr_pvc_rom.c @@ -0,0 +1,251 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include "ixheaac_type_def.h" +#include "iusace_esbr_pvc.h" + +const ixheaace_pvc_tabs_struct ixheaace_pvc_tabs = { + {7.9120074720078801e-002f, 7.8929352455315405e-002f, 7.8356252741836802e-002f, + 7.7397889626247995e-002f, 7.6049149540866515e-002f, 7.4302186813164264e-002f, + 7.2145604983589517e-002f, 6.9563171210312247e-002f, 6.6531787206720316e-002f, + 6.3018197524834882e-002f, 5.8973400826190611e-002f, 5.4322528277253423e-002f, + 4.8944795582858927e-002f, 4.2628371779453236e-002f, 3.4946569619925177e-002f, + 2.4770667091351901e-002f}, + {1.0440702692045410e-001f, 1.0395945931915132e-001f, 1.0261281883061703e-001f, + 1.0035462721037963e-001f, 9.7161686576578310e-002f, 9.2995740369570576e-002f, + 8.7795494664707929e-002f, 8.1461666975864891e-002f, 7.3826916738979523e-002f, + 6.4587661325082549e-002f, 5.3116303570036522e-002f, 3.7720597498577493e-002f}, + {2.9233807677393114e-001f, 2.8099141963307617e-001f, 2.4582604080136389e-001f, + 1.8084446279162875e-001f}, + {3.7911649807579761e-001f, 3.5280765527510910e-001f, 2.6807584664909323e-001f}, + {17, 68}, + {{0xCB, 0xD1, 0xCC, 0xD2, 0xE2, 0xEB, 0xE7, 0xE8}, + {0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}, + {0x84, 0x8C, 0x88, 0x83, 0x90, 0x93, 0x86, 0x80}, + {0xD7, 0xD8, 0xC0, 0xC7, 0xCF, 0xE5, 0xF1, 0xF6}, + {0xA5, 0xA6, 0xAA, 0xA8, 0xB0, 0xB1, 0xB8, 0xB8}, + {0xD7, 0xCB, 0xC1, 0xC3, 0xC5, 0xC9, 0xC9, 0xCE}, + {0xCA, 0xB5, 0xB8, 0xB3, 0xAC, 0xB6, 0xBB, 0xB8}, + {0xC1, 0xC4, 0xC3, 0xC5, 0xC6, 0xCA, 0xCA, 0xCB}, + {0xE0, 0xE1, 0xD8, 0xCD, 0xCB, 0xCB, 0xCE, 0xCC}, + {0xDB, 0xE1, 0xDF, 0xDB, 0xDC, 0xD9, 0xD9, 0xD6}, + {0xE0, 0xDE, 0xDD, 0xDD, 0xE0, 0xE3, 0xE5, 0xE6}, + {0xCA, 0xD2, 0xCD, 0xCE, 0xD5, 0xDB, 0xD9, 0xDB}, + {0xD2, 0xE0, 0xDB, 0xD5, 0xDB, 0xDE, 0xE3, 0xE1}, + {0xE5, 0xDB, 0xD0, 0xD2, 0xD8, 0xDD, 0xDB, 0xDD}, + {0xC0, 0xB5, 0xBF, 0xDD, 0xE3, 0xDC, 0xDC, 0xE4}, + {0xDB, 0xCE, 0xC6, 0xCF, 0xCF, 0xD1, 0xD3, 0xD4}, + {0xC9, 0xD7, 0xDA, 0xE2, 0xE9, 0xE7, 0xDF, 0xDC}, + {0x0A, 0x07, 0x0A, 0x08, 0x19, 0x24, 0x1F, 0x22}, + {0x1E, 0x1F, 0x11, 0x0E, 0x22, 0x2D, 0x33, 0x32}, + {0xF0, 0xDA, 0xDC, 0x18, 0x1F, 0x19, 0x0A, 0x1E}, + {0x09, 0xF8, 0xE6, 0x05, 0x19, 0x11, 0x0E, 0x0B}, + {0x09, 0x10, 0x0E, 0xE6, 0xF4, 0x20, 0x22, 0xFA}, + {0xF2, 0xE5, 0xF8, 0x0E, 0x18, 0x15, 0x0D, 0x10}, + {0x15, 0x13, 0x16, 0x0A, 0x0D, 0x1F, 0x1D, 0x1B}, + {0xFA, 0xFF, 0xFE, 0xFF, 0x09, 0x11, 0x03, 0x0B}, + {0xFE, 0xFA, 0xF2, 0xF8, 0x0C, 0x1E, 0x11, 0x12}, + {0xFA, 0xF8, 0x0B, 0x17, 0x1D, 0x17, 0x0E, 0x16}, + {0x00, 0xF3, 0xFD, 0x0A, 0x1C, 0x17, 0xFD, 0x08}, + {0xEA, 0xEA, 0x03, 0x12, 0x1E, 0x14, 0x09, 0x04}, + {0x02, 0xFE, 0x04, 0xFB, 0x0C, 0x0E, 0x07, 0x02}, + {0xF6, 0x02, 0x07, 0x0B, 0x17, 0x17, 0x01, 0xFF}, + {0xF5, 0xFB, 0xFE, 0x04, 0x12, 0x14, 0x0C, 0x0D}, + {0x10, 0x10, 0x0E, 0x04, 0x07, 0x11, 0x0F, 0x13}, + {0x0C, 0x0F, 0xFB, 0xF2, 0x0A, 0x12, 0x09, 0x0D}, + {0x0D, 0x1D, 0xF1, 0xF4, 0x2A, 0x06, 0x3B, 0x32}, + {0xFC, 0x08, 0x06, 0x02, 0x0E, 0x17, 0x08, 0x0E}, + {0x07, 0x02, 0xEE, 0xEE, 0x2B, 0xF6, 0x23, 0x13}, + {0x04, 0x02, 0x05, 0x08, 0x0B, 0x0E, 0xFB, 0xFB}, + {0x00, 0x04, 0x10, 0x18, 0x22, 0x25, 0x1D, 0x1F}, + {0xFB, 0x0D, 0x07, 0x00, 0x0C, 0x0F, 0xFC, 0x02}, + {0x00, 0x00, 0x00, 0x01, 0x05, 0x07, 0x03, 0x05}, + {0x04, 0x05, 0x08, 0x13, 0xFF, 0xEB, 0x0C, 0x06}, + {0x05, 0x13, 0x0E, 0x0B, 0x12, 0x15, 0x09, 0x0A}, + {0x09, 0x03, 0x09, 0x05, 0x12, 0x16, 0x11, 0x12}, + {0x14, 0x1A, 0x06, 0x01, 0x10, 0x11, 0xFE, 0x02}, + {0x01, 0x0B, 0x0B, 0x0C, 0x18, 0x21, 0x10, 0x13}, + {0x12, 0x0D, 0x0A, 0x10, 0x1C, 0x1D, 0x0D, 0x10}, + {0x03, 0x09, 0x14, 0x15, 0x1B, 0x1A, 0x01, 0xFF}, + {0x08, 0x12, 0x13, 0x0E, 0x16, 0x1D, 0x14, 0x1B}, + {0x07, 0x15, 0x1C, 0x1B, 0x20, 0x21, 0x11, 0x0E}, + {0x12, 0x18, 0x19, 0x17, 0x20, 0x25, 0x1A, 0x1E}, + {0x0C, 0x1A, 0x1D, 0x22, 0x2F, 0x33, 0x27, 0x28}, + {0x0E, 0x1A, 0x17, 0x10, 0x0A, 0x0E, 0xFF, 0x06}, + {0x1A, 0x1C, 0x18, 0x14, 0x1A, 0x16, 0x0A, 0x0E}, + {0x1E, 0x27, 0x25, 0x26, 0x27, 0x2A, 0x21, 0x21}, + {0xF1, 0x0A, 0x16, 0x1C, 0x28, 0x25, 0x15, 0x19}, + {0x08, 0x12, 0x09, 0x08, 0x16, 0x17, 0xEF, 0xF6}, + {0x0C, 0x0B, 0x00, 0xFC, 0x04, 0x09, 0xFC, 0x03}, + {0xFB, 0xF1, 0xF8, 0x26, 0x24, 0x18, 0x1D, 0x20}, + {0xF9, 0x01, 0x0C, 0x0F, 0x07, 0x08, 0x06, 0x07}, + {0x07, 0x06, 0x08, 0x04, 0x07, 0x0D, 0x07, 0x09}, + {0xFE, 0x01, 0x06, 0x05, 0x13, 0x1B, 0x14, 0x19}, + {0x09, 0x0C, 0x0E, 0x01, 0x08, 0x05, 0xFB, 0xFD}, + {0x07, 0x06, 0x03, 0x0A, 0x16, 0x12, 0x04, 0x07}, + {0x04, 0x01, 0x00, 0x04, 0x1F, 0x20, 0x0E, 0x0A}, + {0x03, 0xFF, 0xF6, 0xFB, 0x15, 0x1A, 0x00, 0x03}, + {0xFC, 0x18, 0x0B, 0x2D, 0x35, 0x23, 0x12, 0x09}, + {0x02, 0xFE, 0x01, 0xFF, 0x0C, 0x11, 0x0D, 0x0F}, + {0xFA, 0xE9, 0xD9, 0xFF, 0x0D, 0x05, 0x0D, 0x10}, + {0xF1, 0xE0, 0xF0, 0x01, 0x06, 0x06, 0x06, 0x10}, + {0xE9, 0xD4, 0xD7, 0x0F, 0x14, 0x0B, 0x0D, 0x16}, + {0x00, 0xFF, 0xEE, 0xE5, 0xFF, 0x08, 0x02, 0xF9}, + {0xE0, 0xDA, 0xE5, 0xFE, 0x09, 0x02, 0xF9, 0x04}, + {0xE0, 0xE2, 0xF4, 0x09, 0x13, 0x0C, 0x0D, 0x09}, + {0xFC, 0x02, 0x04, 0xFF, 0x00, 0xFF, 0xF8, 0xF7}, + {0xFE, 0xFB, 0xED, 0xF2, 0xFE, 0xFE, 0x08, 0x0C}, + {0xF3, 0xEF, 0xD0, 0xE3, 0x05, 0x11, 0xFD, 0xFF}, + {0xFA, 0xEF, 0xEA, 0xFE, 0x0D, 0x0E, 0xFE, 0x02}, + {0xF7, 0xFB, 0xDB, 0xDF, 0x14, 0xDD, 0x07, 0xFE}, + {0xFE, 0x08, 0x00, 0xDB, 0xE5, 0x1A, 0x13, 0xED}, + {0xF9, 0xFE, 0xFF, 0xF4, 0xF3, 0x00, 0x05, 0x02}, + {0xEF, 0xDE, 0xD8, 0xEB, 0xEA, 0xF5, 0x0E, 0x19}, + {0xFB, 0xFC, 0xFA, 0xEC, 0xEB, 0xED, 0xEE, 0xE8}, + {0xEE, 0xFC, 0xFD, 0x00, 0x04, 0xFC, 0xF0, 0xF5}, + {0x00, 0xFA, 0xF4, 0xF1, 0xF5, 0xFA, 0xFB, 0xF9}, + {0xEB, 0xF0, 0xDF, 0xE3, 0xEF, 0x07, 0x02, 0x05}, + {0xF7, 0xF0, 0xE6, 0xE7, 0x06, 0x15, 0x06, 0x0C}, + {0xF1, 0xE4, 0xD8, 0xEA, 0x06, 0xF2, 0x07, 0x09}, + {0xFF, 0xFE, 0xFE, 0xF9, 0xFF, 0xFF, 0x02, 0xF9}, + {0xDD, 0xF4, 0xF0, 0xF1, 0xFF, 0xFF, 0xEA, 0xF1}, + {0xF0, 0xF1, 0xFD, 0x03, 0x03, 0xFE, 0x00, 0x05}, + {0xF1, 0xF6, 0xE0, 0xDF, 0xF5, 0x01, 0xF4, 0xF8}, + {0x02, 0x03, 0xE5, 0xDC, 0xE7, 0xFD, 0x02, 0x08}, + {0xEC, 0xF1, 0xF5, 0xEC, 0xF2, 0xF8, 0xF6, 0xEE}, + {0xF3, 0xF4, 0xF6, 0xF4, 0xF5, 0xF1, 0xE7, 0xEA}, + {0xF7, 0xF3, 0xEC, 0xEA, 0xEF, 0xF0, 0xEE, 0xF1}, + {0xEB, 0xF6, 0xFB, 0xFA, 0xEF, 0xF3, 0xF3, 0xF7}, + {0x01, 0x03, 0xF1, 0xF6, 0x05, 0xF8, 0xE1, 0xEB}, + {0xF5, 0xF6, 0xF6, 0xF4, 0xFB, 0xFB, 0xFF, 0x00}, + {0xF8, 0x01, 0xFB, 0xFA, 0xFF, 0x03, 0xFE, 0x04}, + {0x04, 0xFB, 0x03, 0xFD, 0xF5, 0xF7, 0xF6, 0xFB}, + {0x06, 0x09, 0xFB, 0xF4, 0xF9, 0xFA, 0xFC, 0xFF}, + {0xF5, 0xF6, 0xF1, 0xEE, 0xF5, 0xF8, 0xF5, 0xF9}, + {0xF5, 0xF9, 0xFA, 0xFC, 0x07, 0x09, 0x01, 0xFB}, + {0xD7, 0xE9, 0xE8, 0xEC, 0x00, 0x0C, 0xFE, 0xF1}, + {0xEC, 0x04, 0xE9, 0xDF, 0x03, 0xE8, 0x00, 0xFA}, + {0xE6, 0xE2, 0xFF, 0x0A, 0x13, 0x01, 0x00, 0xF7}, + {0xF1, 0xFA, 0xF7, 0xF5, 0x01, 0x06, 0x05, 0x0A}, + {0xF6, 0xF6, 0xFC, 0xF6, 0xE8, 0x11, 0xF2, 0xFE}, + {0xFE, 0x08, 0x05, 0x12, 0xFD, 0xD0, 0x0E, 0x07}, + {0xF1, 0xFE, 0xF7, 0xF2, 0xFB, 0x02, 0xFA, 0xF8}, + {0xF4, 0xEA, 0xEC, 0xF3, 0xFE, 0x01, 0xF7, 0xF6}, + {0xFF, 0xFA, 0xFB, 0xF9, 0xFF, 0x01, 0x04, 0x03}, + {0x00, 0xF9, 0xF4, 0xFC, 0x05, 0xFC, 0xF7, 0xFB}, + {0xF8, 0xFF, 0xEF, 0xEC, 0xFB, 0x04, 0xF8, 0x03}, + {0xEB, 0xF1, 0xED, 0xF4, 0x02, 0x0E, 0x0B, 0x04}, + {0xF7, 0x01, 0xF8, 0xF4, 0xF8, 0xEF, 0xF8, 0x04}, + {0xEB, 0xF0, 0xF7, 0xFC, 0x10, 0x0D, 0xF8, 0xF8}, + {0xE8, 0xFE, 0xEE, 0xE8, 0xED, 0xF7, 0xF5, 0xF8}, + {0xED, 0xEB, 0xE9, 0xEA, 0xF2, 0xF5, 0xF4, 0xF9}, + {0xEA, 0xF2, 0xEF, 0xEE, 0xF9, 0xFE, 0xFD, 0x02}, + {0xFA, 0xFD, 0x02, 0x0D, 0xFA, 0xE4, 0x0F, 0x01}, + {0xFF, 0x08, 0x05, 0xF6, 0xF7, 0xFB, 0xF1, 0xF1}, + {0xF4, 0xEC, 0xEE, 0xF6, 0xEE, 0xEE, 0xF8, 0x06}, + {0xE8, 0xFA, 0xF8, 0xE8, 0xF8, 0xE9, 0xEE, 0xF9}, + {0xE5, 0xE9, 0xF0, 0x00, 0x00, 0xEF, 0xF3, 0xF8}, + {0xF7, 0xFB, 0xFB, 0xF7, 0xF9, 0xF9, 0xF5, 0xF0}, + {0xFD, 0xFF, 0xF2, 0xEE, 0xF2, 0xF5, 0xF1, 0xF3}}, + {{{0x4F, 0x5B, 0x57, 0x52, 0x4D, 0x65, 0x45, 0x57}, + {0xF3, 0x0F, 0x18, 0x20, 0x19, 0x4F, 0x3D, 0x23}, + {0x78, 0x57, 0x55, 0x50, 0x50, 0x20, 0x36, 0x37}}, + {{0x4C, 0x5F, 0x53, 0x37, 0x1E, 0xFD, 0x15, 0x0A}, + {0x05, 0x0E, 0x28, 0x41, 0x48, 0x6E, 0x54, 0x5B}, + {0x59, 0x47, 0x40, 0x40, 0x3D, 0x33, 0x3F, 0x39}}, + {{0x47, 0x5F, 0x57, 0x34, 0x3C, 0x2E, 0x2E, 0x31}, + {0xFA, 0x13, 0x23, 0x4E, 0x44, 0x7C, 0x34, 0x38}, + {0x63, 0x43, 0x41, 0x3D, 0x35, 0x19, 0x3D, 0x33}}}, + {1.0 / 256.0, 1.0 / 256.0, 1.0 / 128.0, 1.0 / 2.0}, + {16, 52}, + {{0x26, 0x25, 0x11, 0x0C, 0xFA, 0x15}, {0x1B, 0x18, 0x11, 0x0E, 0x0E, 0x0E}, + {0x12, 0x10, 0x10, 0x10, 0x11, 0x10}, {0x1E, 0x24, 0x19, 0x15, 0x14, 0x12}, + {0x24, 0x16, 0x12, 0x13, 0x15, 0x1C}, {0xEA, 0xED, 0xEB, 0xEA, 0xEC, 0xEB}, + {0xFC, 0xFD, 0xFD, 0xFC, 0xFE, 0xFE}, {0x0F, 0x0C, 0x0B, 0x0A, 0x0B, 0x0B}, + {0x22, 0x0B, 0x16, 0x18, 0x13, 0x19}, {0x1C, 0x14, 0x1D, 0x20, 0x19, 0x1A}, + {0x10, 0x08, 0x00, 0xFF, 0x02, 0x05}, {0x06, 0x07, 0x05, 0x03, 0x05, 0x04}, + {0x2A, 0x1F, 0x12, 0x12, 0x11, 0x18}, {0x19, 0x19, 0x02, 0x04, 0x00, 0x04}, + {0x18, 0x17, 0x17, 0x15, 0x16, 0x15}, {0x21, 0x1E, 0x1B, 0x19, 0x1C, 0x1B}, + {0x3C, 0x35, 0x20, 0x1D, 0x30, 0x34}, {0x3A, 0x1F, 0x37, 0x38, 0x33, 0x31}, + {0x37, 0x34, 0x25, 0x27, 0x35, 0x34}, {0x34, 0x2E, 0x32, 0x31, 0x34, 0x31}, + {0x36, 0x33, 0x2F, 0x2F, 0x32, 0x2F}, {0x35, 0x20, 0x2F, 0x32, 0x2F, 0x2C}, + {0x2E, 0x2B, 0x2F, 0x34, 0x36, 0x30}, {0x3F, 0x39, 0x30, 0x28, 0x29, 0x29}, + {0x3C, 0x30, 0x32, 0x37, 0x39, 0x36}, {0x37, 0x36, 0x30, 0x2B, 0x26, 0x24}, + {0x44, 0x38, 0x2F, 0x2D, 0x2D, 0x2D}, {0x38, 0x2B, 0x2C, 0x2C, 0x30, 0x2D}, + {0x37, 0x36, 0x2F, 0x23, 0x2D, 0x32}, {0x3C, 0x39, 0x29, 0x2E, 0x38, 0x37}, + {0x3B, 0x3A, 0x35, 0x32, 0x31, 0x2D}, {0x32, 0x31, 0x2F, 0x2C, 0x2D, 0x28}, + {0x2C, 0x31, 0x32, 0x30, 0x32, 0x2D}, {0x35, 0x34, 0x34, 0x34, 0x35, 0x33}, + {0x34, 0x38, 0x3B, 0x3C, 0x3E, 0x3A}, {0x3E, 0x3C, 0x3B, 0x3A, 0x3C, 0x39}, + {0x3D, 0x41, 0x46, 0x41, 0x3D, 0x38}, {0x44, 0x41, 0x40, 0x3E, 0x3F, 0x3A}, + {0x47, 0x47, 0x47, 0x42, 0x44, 0x40}, {0x4C, 0x4A, 0x4A, 0x46, 0x49, 0x45}, + {0x53, 0x52, 0x52, 0x4C, 0x4E, 0x49}, {0x41, 0x3D, 0x39, 0x2C, 0x2E, 0x2E}, + {0x2D, 0x37, 0x36, 0x30, 0x28, 0x36}, {0x3B, 0x32, 0x2E, 0x2D, 0x2D, 0x29}, + {0x40, 0x39, 0x36, 0x35, 0x36, 0x32}, {0x30, 0x2D, 0x2D, 0x2E, 0x31, 0x30}, + {0x38, 0x3D, 0x3B, 0x37, 0x35, 0x34}, {0x44, 0x3D, 0x3C, 0x38, 0x37, 0x33}, + {0x3A, 0x36, 0x37, 0x37, 0x39, 0x36}, {0x32, 0x36, 0x37, 0x30, 0x2E, 0x2A}, + {0x3C, 0x33, 0x33, 0x31, 0x33, 0x30}, {0x30, 0x31, 0x36, 0x37, 0x38, 0x34}, + {0x26, 0x27, 0x2E, 0x29, 0x1C, 0x16}, {0x14, 0x15, 0x1F, 0x17, 0x15, 0x1C}, + {0x38, 0x2D, 0x18, 0x13, 0x1E, 0x2B}, {0x30, 0x22, 0x17, 0x1A, 0x26, 0x2B}, + {0x24, 0x20, 0x1F, 0x10, 0x0C, 0x11}, {0x27, 0x1F, 0x13, 0x17, 0x24, 0x2A}, + {0x2F, 0x13, 0x18, 0x13, 0x2A, 0x32}, {0x31, 0x1E, 0x1E, 0x1E, 0x21, 0x28}, + {0x2A, 0x12, 0x19, 0x17, 0x16, 0x24}, {0x27, 0x0F, 0x16, 0x1D, 0x17, 0x1C}, + {0x2F, 0x26, 0x25, 0x22, 0x20, 0x22}, {0x1E, 0x1B, 0x1E, 0x18, 0x1E, 0x24}, + {0x31, 0x26, 0x0E, 0x15, 0x15, 0x25}, {0x2D, 0x22, 0x1E, 0x14, 0x10, 0x22}, + {0x25, 0x1B, 0x18, 0x11, 0x13, 0x1F}, {0x2F, 0x1B, 0x13, 0x1B, 0x18, 0x22}, + {0x21, 0x24, 0x1D, 0x1C, 0x1D, 0x1B}, {0x23, 0x1E, 0x28, 0x29, 0x27, 0x25}, + {0x2E, 0x2A, 0x1D, 0x17, 0x26, 0x2D}, {0x31, 0x2C, 0x1A, 0x0E, 0x1A, 0x24}, + {0x26, 0x16, 0x20, 0x1D, 0x14, 0x1E}, {0x29, 0x20, 0x1B, 0x1B, 0x17, 0x17}, + {0x1D, 0x06, 0x1A, 0x1E, 0x1B, 0x1D}, {0x2B, 0x23, 0x1F, 0x1F, 0x1D, 0x1C}, + {0x27, 0x1A, 0x0C, 0x0E, 0x0F, 0x1A}, {0x29, 0x1D, 0x1E, 0x22, 0x22, 0x24}, + {0x20, 0x21, 0x1B, 0x18, 0x13, 0x21}, {0x27, 0x0E, 0x10, 0x14, 0x10, 0x1A}, + {0x26, 0x24, 0x25, 0x25, 0x26, 0x28}, {0x1A, 0x24, 0x25, 0x29, 0x26, 0x24}, + {0x1D, 0x1D, 0x15, 0x12, 0x0F, 0x18}, {0x1E, 0x14, 0x13, 0x12, 0x14, 0x18}, + {0x16, 0x13, 0x13, 0x1A, 0x1B, 0x1D}, {0x20, 0x27, 0x22, 0x24, 0x1A, 0x19}, + {0x1F, 0x17, 0x19, 0x18, 0x17, 0x18}, {0x20, 0x1B, 0x1C, 0x1C, 0x1B, 0x1A}, + {0x23, 0x19, 0x1D, 0x1F, 0x1E, 0x21}, {0x26, 0x1F, 0x1D, 0x1B, 0x19, 0x1A}, + {0x23, 0x1E, 0x1F, 0x20, 0x1F, 0x1E}, {0x29, 0x20, 0x22, 0x20, 0x20, 0x1F}, + {0x26, 0x23, 0x21, 0x22, 0x23, 0x23}, {0x29, 0x1F, 0x24, 0x25, 0x26, 0x29}, + {0x2B, 0x22, 0x25, 0x27, 0x23, 0x21}, {0x29, 0x21, 0x19, 0x0E, 0x22, 0x2D}, + {0x32, 0x29, 0x1F, 0x1C, 0x1B, 0x21}, {0x1E, 0x1A, 0x1E, 0x24, 0x25, 0x25}, + {0x24, 0x1D, 0x21, 0x22, 0x22, 0x25}, {0x2C, 0x25, 0x21, 0x22, 0x23, 0x25}, + {0x24, 0x1E, 0x21, 0x26, 0x2B, 0x2C}, {0x28, 0x24, 0x1B, 0x1F, 0x28, 0x2D}, + {0x23, 0x13, 0x16, 0x22, 0x22, 0x29}, {0x1B, 0x23, 0x1C, 0x20, 0x14, 0x0D}, + {0x1E, 0x16, 0x1A, 0x1E, 0x1C, 0x1D}, {0x2B, 0x1C, 0x1D, 0x20, 0x1B, 0x1C}, + {0x1C, 0x1B, 0x23, 0x1F, 0x19, 0x1E}, {0x21, 0x23, 0x26, 0x20, 0x20, 0x22}, + {0x1D, 0x0B, 0x19, 0x1E, 0x11, 0x19}, {0x18, 0x17, 0x16, 0x17, 0x14, 0x16}, + {0x16, 0x19, 0x1C, 0x20, 0x21, 0x22}, {0x30, 0x1E, 0x22, 0x24, 0x25, 0x26}, + {0x1B, 0x1F, 0x17, 0x1D, 0x1E, 0x21}, {0x32, 0x2B, 0x27, 0x1F, 0x1B, 0x1A}, + {0x28, 0x20, 0x1A, 0x1B, 0x1F, 0x23}, {0x32, 0x21, 0x20, 0x21, 0x1D, 0x1F}, + {0x22, 0x18, 0x12, 0x15, 0x1B, 0x20}, {0x27, 0x27, 0x2A, 0x24, 0x21, 0x21}, + {0x1E, 0x0F, 0x0D, 0x1A, 0x1D, 0x23}, {0x28, 0x25, 0x27, 0x21, 0x17, 0x25}, + {0x2B, 0x27, 0x23, 0x19, 0x13, 0x14}, {0x25, 0x2B, 0x22, 0x22, 0x20, 0x21}, + {0x27, 0x1B, 0x16, 0x17, 0x0F, 0x15}, {0x29, 0x26, 0x23, 0x15, 0x1E, 0x28}, + {0x24, 0x1C, 0x19, 0x1A, 0x18, 0x19}, {0x2D, 0x15, 0x27, 0x2B, 0x24, 0x23}, + {0x2C, 0x12, 0x1F, 0x23, 0x1F, 0x20}, {0x25, 0x0F, 0x22, 0x27, 0x1F, 0x21}}, + {{{0x11, 0x27, 0x0F, 0xFD, 0x04, 0xFC}, + {0x00, 0xBE, 0xE3, 0xF4, 0xDB, 0xF0}, + {0x09, 0x1E, 0x18, 0x1A, 0x21, 0x1B}}, + {{0x16, 0x28, 0x2B, 0x29, 0x25, 0x32}, + {0xF2, 0xE9, 0xE4, 0xE5, 0xE2, 0xD4}, + {0x0E, 0x0B, 0x0C, 0x0D, 0x0D, 0x0E}}, + {{0x2E, 0x3C, 0x20, 0x16, 0x1B, 0x1A}, + {0xE4, 0xC6, 0xE5, 0xF4, 0xDC, 0xDC}, + {0x0F, 0x1B, 0x18, 0x14, 0x1E, 0x1A}}}, + {1.0 / 128.0, 1.0 / 128.0, 1.0 / 64.0, 1.0 / 1.0}}; diff --git a/encoder/iusace_esbr_rom.c b/encoder/iusace_esbr_rom.c new file mode 100644 index 0000000..24a317a --- /dev/null +++ b/encoder/iusace_esbr_rom.c @@ -0,0 +1,32 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include + +#include "ixheaac_type_def.h" +#include "ixheaace_aac_constants.h" +#include "iusace_esbr_rom.h" + +const FLOAT32 ixheaace_gamma_tab[4] = {0.0f, 1.0f, 2.0f, 4.0f}; + +const FLOAT32 ixheaace_new_bw_tab[4][4] = {{0.00f, 0.60f, 0.90f, 0.98f}, + {0.60f, 0.75f, 0.90f, 0.98f}, + {0.00f, 0.75f, 0.90f, 0.98f}, + {0.00f, 0.75f, 0.90f, 0.98f}}; diff --git a/encoder/iusace_esbr_rom.h b/encoder/iusace_esbr_rom.h new file mode 100644 index 0000000..2b4c21f --- /dev/null +++ b/encoder/iusace_esbr_rom.h @@ -0,0 +1,24 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once + +extern const FLOAT32 ixheaace_gamma_tab[4]; +extern const FLOAT32 ixheaace_new_bw_tab[4][4]; diff --git a/encoder/iusace_fd_enc.h b/encoder/iusace_fd_enc.h new file mode 100644 index 0000000..396f017 --- /dev/null +++ b/encoder/iusace_fd_enc.h @@ -0,0 +1,26 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +IA_ERRORCODE iusace_fd_encode(ia_sfb_params_struct *pstr_sfb_prms, WORD32 usac_independancy_flag, + ia_usac_data_struct *pstr_usac_data, + ia_usac_encoder_config_struct *pstr_usac_config, + ia_bit_buf_struct *pstr_it_bit_buff, WORD32 nr_core_coder_ch, + WORD32 chn, WORD32 ele_id, WORD32 *bit_written); diff --git a/encoder/iusace_fd_fac.c b/encoder/iusace_fd_fac.c new file mode 100644 index 0000000..d4c5ff9 --- /dev/null +++ b/encoder/iusace_fd_fac.c @@ -0,0 +1,328 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include +#include "ixheaac_type_def.h" +#include "ixheaace_adjust_threshold_data.h" +#include "iusace_bitbuffer.h" +#include "ixheaace_mps_common_define.h" +/* DRC */ +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" +#include "impd_drc_uni_drc_eq.h" +#include "impd_drc_uni_drc_filter_bank.h" +#include "impd_drc_gain_enc.h" +#include "impd_drc_struct_def.h" + +#include "iusace_cnst.h" +#include "iusace_tns_usac.h" +#include "iusace_psy_mod.h" +#include "iusace_ms.h" +#include "iusace_fd_qc_util.h" +#include "ixheaace_memory_standards.h" +#include "iusace_config.h" +#include "iusace_tcx_mdct.h" +#include "iusace_arith_enc.h" +#include "iusace_fd_quant.h" +#include "iusace_signal_classifier.h" +#include "iusace_block_switch_const.h" +#include "iusace_block_switch_struct_def.h" +#include "ixheaace_sbr_header.h" +#include "ixheaace_config.h" +#include "ixheaace_asc_write.h" +#include "iusace_main.h" +#include "iusace_func_prototypes.h" +#include "iusace_lpd_rom.h" +#include "iusace_lpd.h" +#include "iusace_avq_enc.h" +#include "ixheaac_error_standards.h" +#include "ixheaace_error_codes.h" + +static VOID iusace_decode_fd_fac(WORD32 *ptr_fac_prms, WORD32 len_subfrm, WORD32 fac_len, + FLOAT32 *ptr_lpc_coeffs, FLOAT32 *zir_sig, FLOAT32 *ptr_fac_dec, + iusace_scratch_mem *pstr_scratch) { + FLOAT32 *x = pstr_scratch->p_x; + FLOAT32 *xn2 = pstr_scratch->p_xn_2; + FLOAT32 fac_gain; + WORD32 i; + const FLOAT32 *sin_window; + FLOAT32 *fac_window = pstr_scratch->p_fac_window; + FLOAT32 ap[ORDER + 1]; + + if (fac_len == 64) { + sin_window = iusace_sin_window_128; + } else { + sin_window = iusace_sin_window_256; + } + + if (ptr_lpc_coeffs != NULL && ptr_fac_dec != NULL) { + fac_gain = (FLOAT32)pow(10.0f, ((FLOAT32)ptr_fac_prms[0]) / 28.0f); + for (i = 0; i < fac_len; i++) { + x[i] = (FLOAT32)ptr_fac_prms[i + 1] * fac_gain; + } + + iusace_tcx_mdct(x, xn2, fac_len, pstr_scratch); + + iusace_get_weighted_lpc(ptr_lpc_coeffs, ap); + + memset(xn2 + fac_len, 0, fac_len * sizeof(FLOAT32)); + iusace_synthesis_tool_float(ap, xn2, ptr_fac_dec, 2 * fac_len, xn2 + fac_len, + pstr_scratch->p_buf_synthesis_tool); + + if (zir_sig != NULL) { + for (i = 0; i < fac_len; i++) { + fac_window[i] = sin_window[i] * sin_window[(2 * fac_len) - 1 - i]; + fac_window[fac_len + i] = 1.0f - (sin_window[fac_len + i] * sin_window[fac_len + i]); + } + for (i = 0; i < fac_len; i++) { + ptr_fac_dec[i] += zir_sig[1 + (len_subfrm / 2) + i] * fac_window[fac_len + i] + + zir_sig[1 + (len_subfrm / 2) - 1 - i] * fac_window[fac_len - 1 - i]; + } + } + } + + return; +} + +VOID iusace_fac_apply(FLOAT32 *orig, WORD32 len_subfrm, WORD32 fac_len, WORD32 low_pass_line, + WORD32 target_br, FLOAT32 *synth, FLOAT32 *ptr_lpc_coeffs, + WORD16 *fac_bits_word, WORD32 *num_fac_bits, + iusace_scratch_mem *pstr_scratch) { + FLOAT32 *xn2 = pstr_scratch->p_xn2; + FLOAT32 *fac_dec = pstr_scratch->p_fac_dec; + FLOAT32 *right_fac_spec = pstr_scratch->p_right_fac_spec; + FLOAT32 *x2 = pstr_scratch->p_x2; + WORD32 *param = pstr_scratch->p_param; + FLOAT32 ap[ORDER + 1]; + FLOAT32 fac_gain; + WORD32 i, index; + WORD32 num_enc_bits = 0; + WORD32 start_right = 2 * len_subfrm - fac_len; + + *num_fac_bits = 0; + + memset(xn2, 0, (FAC_LENGTH + ORDER) * sizeof(FLOAT32)); + + memcpy(xn2 + ORDER, &orig[start_right], fac_len * sizeof(FLOAT32)); + for (i = 0; i < fac_len; i++) { + xn2[ORDER + i] -= synth[start_right + i]; + } + + iusace_get_weighted_lpc(ptr_lpc_coeffs, ap); + iusace_compute_lp_residual(ap, xn2 + ORDER, x2, fac_len); + for (i = 0; i < fac_len; i++) { + x2[i] = x2[i] * (2.0f / (FLOAT32)fac_len); + } + + iusace_tcx_mdct(x2, right_fac_spec, fac_len, pstr_scratch); + + memset(&right_fac_spec[low_pass_line], 0, (fac_len - low_pass_line) * sizeof(FLOAT32)); + + fac_gain = iusace_calc_sq_gain(right_fac_spec, target_br, fac_len, pstr_scratch->p_sq_gain_en); + index = (WORD32)floor(0.5f + (28.0f * (FLOAT32)log10(fac_gain))); + if (index < 0) index = 0; + if (index > 127) index = 127; + param[0] = index; + fac_gain = (FLOAT32)pow(10.0f, ((FLOAT32)index) / 28.0f); + for (i = 0; i < fac_len; i++) right_fac_spec[i] /= fac_gain; + + for (i = 0; i < fac_len; i += 8) { + iusace_find_nearest_neighbor(&right_fac_spec[i], ¶m[i + 1]); + } + + iusace_write_bits2buf(index, 7, fac_bits_word); + num_enc_bits += 7; + num_enc_bits += iusace_fd_encode_fac(¶m[1], &fac_bits_word[7], fac_len); + iusace_decode_fd_fac(¶m[0], len_subfrm, fac_len, ptr_lpc_coeffs, NULL, fac_dec, + pstr_scratch); + *num_fac_bits = num_enc_bits; + + for (i = 0; i < fac_len; i++) { + synth[start_right + i] += fac_dec[i]; + } + return; +} + +IA_ERRORCODE iusace_fd_fac(WORD32 *sfb_offsets, WORD32 sfb_active, FLOAT64 *orig_sig_dbl, + WORD32 window_sequence, FLOAT64 *synth_time, + ia_usac_td_encoder_struct *pstr_acelp, WORD32 last_subfr_was_acelp, + WORD32 next_frm_lpd, WORD16 *fac_prm_out, WORD32 *num_fac_bits, + iusace_scratch_mem *pstr_scratch) { + const FLOAT32 *sin_window = NULL; + LOOPIDX i; + FLOAT32 *zir_sig = NULL; + FLOAT32 *lpc_coeffs_q = NULL; + WORD32 index; + WORD32 low_pass_line; + WORD32 fac_len; + FLOAT64 *left_fac_time_data = pstr_scratch->p_left_fac_time_data; + FLOAT32 *left_fac_timedata_flt = pstr_scratch->p_left_fac_timedata_flt; + FLOAT32 *left_fac_spec = pstr_scratch->p_left_fac_spec; + FLOAT64 *fac_win = pstr_scratch->p_fac_win; + WORD32 *fac_prm = pstr_scratch->p_fac_prm; + WORD16 *fac_bits_word = pstr_scratch->p_fac_bits_word; + FLOAT32 *acelp_folded = pstr_scratch->p_acelp_folded_scratch; + + *num_fac_bits = 0; + + if (window_sequence == EIGHT_SHORT_SEQUENCE) + fac_len = (pstr_acelp->len_frame / 16); + else + fac_len = (pstr_acelp->len_frame / 8); + + low_pass_line = (WORD32)((FLOAT32)sfb_offsets[sfb_active] * (FLOAT32)fac_len / + (FLOAT32)pstr_acelp->len_frame); + if (last_subfr_was_acelp) { + FLOAT32 *tmp_lp_res = pstr_scratch->ptr_tmp_lp_res; + FLOAT32 lpc_coeffs[ORDER + 1]; + FLOAT32 ener, fac_gain; + WORD32 left_start; + + switch (fac_len) { + case 48: + sin_window = iusace_sin_window_96; + break; + case 64: + sin_window = iusace_sin_window_128; + break; + case 96: + sin_window = iusace_sin_window_192; + break; + case 128: + sin_window = iusace_sin_window_256; + break; + default: + return IA_EXHEAACE_EXE_FATAL_USAC_INVALID_FAC_LEN; + } + + for (i = 0; i < fac_len; i++) { + fac_win[i] = sin_window[i] * sin_window[(2 * fac_len) - 1 - i]; + fac_win[fac_len + i] = 1.0f - (sin_window[fac_len + i] * sin_window[fac_len + i]); + } + + left_start = (pstr_acelp->len_frame / 2) - fac_len - ORDER; + + for (i = 0; i < 2 * fac_len + ORDER; i++) { + left_fac_time_data[i] = orig_sig_dbl[left_start + i]; + } + + for (i = 0; i < fac_len; i++) { + left_fac_time_data[fac_len + ORDER + i] = + left_fac_time_data[fac_len + ORDER + i] - synth_time[left_start + fac_len + ORDER + i]; + } + + zir_sig = pstr_acelp->lpd_state.tcx_quant; + + for (i = 0; i < ORDER; i++) { + left_fac_time_data[fac_len + i] = + left_fac_time_data[fac_len + i] - zir_sig[1 + 128 - ORDER + i]; + } + + for (i = 0; i < fac_len; i++) { + acelp_folded[i] = zir_sig[1 + 128 + i] * (FLOAT32)fac_win[fac_len + i] + + zir_sig[1 + 128 - 1 - i] * (FLOAT32)fac_win[fac_len - 1 - i]; + } + + { + FLOAT32 ener_tmp; + ener = 0.0f; + ener_tmp = 0.0f; + + for (i = 0; i < fac_len; i++) { + ener += (FLOAT32)(left_fac_time_data[i + ORDER + fac_len] * + left_fac_time_data[i + ORDER + fac_len]); + } + ener *= 2.0f; + + for (i = 0; i < fac_len; i++) { + ener_tmp += acelp_folded[i] * acelp_folded[i]; + } + + if (ener_tmp > ener) + fac_gain = (FLOAT32)sqrt(ener / ener_tmp); + else + fac_gain = 1.0f; + + for (i = 0; i < fac_len; i++) { + left_fac_time_data[i + ORDER + fac_len] -= fac_gain * acelp_folded[i]; + } + } + + for (i = 0; i < 2 * fac_len + ORDER; i++) { + left_fac_timedata_flt[i] = (FLOAT32)left_fac_time_data[i]; + } + + lpc_coeffs_q = pstr_acelp->lpd_state.lpc_coeffs_quant; + lpc_coeffs_q += ORDER + 1; + iusace_get_weighted_lpc(lpc_coeffs_q, lpc_coeffs); + iusace_compute_lp_residual(lpc_coeffs, left_fac_timedata_flt + ORDER + fac_len, tmp_lp_res, + fac_len); + FLOAT32 coeff = (2.0f / (FLOAT32)fac_len); + for (i = 0; i < fac_len; i++) { + tmp_lp_res[i] = tmp_lp_res[i] * coeff; + } + + iusace_tcx_mdct(tmp_lp_res, left_fac_spec, fac_len, pstr_scratch); + memset(&left_fac_spec[low_pass_line], 0, (fac_len - low_pass_line) * sizeof(FLOAT32)); + + fac_gain = iusace_calc_sq_gain(left_fac_spec, 240, fac_len, pstr_scratch->p_sq_gain_en); + + index = (WORD32)floor(0.5f + (28.0f * (FLOAT32)log10(fac_gain))); + if (index < 0) index = 0; + if (index > 127) index = 127; + iusace_write_bits2buf(index, 7, fac_bits_word); + *num_fac_bits += 7; + fac_gain = (FLOAT32)pow(10.0f, ((FLOAT32)index) / 28.0f); + + for (i = 0; i < fac_len; i++) { + left_fac_spec[i] /= fac_gain; + } + + for (i = 0; i < fac_len; i += 8) { + iusace_find_nearest_neighbor(&left_fac_spec[i], &fac_prm[i]); + } + + *num_fac_bits += iusace_fd_encode_fac(fac_prm, &fac_bits_word[7], fac_len); + + for (i = 0; i < (*num_fac_bits + 7) / 8; i++) { + fac_prm_out[i] = + (WORD16)((fac_bits_word[8 * i + 0] & 0x1) << 7 | (fac_bits_word[8 * i + 1] & 0x1) << 6 | + (fac_bits_word[8 * i + 2] & 0x1) << 5 | (fac_bits_word[8 * i + 3] & 0x1) << 4 | + (fac_bits_word[8 * i + 4] & 0x1) << 3 | (fac_bits_word[8 * i + 5] & 0x1) << 2 | + (fac_bits_word[8 * i + 6] & 0x1) << 1 | (fac_bits_word[8 * i + 7] & 0x1) << 0); + } + } else { + *num_fac_bits = 0; + } + + if (next_frm_lpd) { + for (i = 0; i < 1024 / 2 + 1 + ORDER; i++) { + pstr_acelp->fd_synth[i] = (FLOAT32)synth_time[pstr_acelp->len_frame - 1 + i - ORDER]; + pstr_acelp->fd_orig[i] = (FLOAT32)orig_sig_dbl[pstr_acelp->len_frame + i - ORDER]; + } + + pstr_acelp->low_pass_line = low_pass_line; + } + + return IA_NO_ERROR; +} diff --git a/encoder/iusace_fd_qc_adjthr.h b/encoder/iusace_fd_qc_adjthr.h new file mode 100644 index 0000000..dd90b72 --- /dev/null +++ b/encoder/iusace_fd_qc_adjthr.h @@ -0,0 +1,104 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +#define RED_EXP_VAL 0.25f +#define INV_RED_EXP_VAL (1.0f / RED_EXP_VAL) +#define MIN_SNR_LIMIT 0.8f + +#define MAX_SCF_DELTA 60 + +#define LOG2_1 1.442695041f +#define C1_SF -69.33295f /* -16/3*log(MAX_QUANT+0.5-logCon)/log(2) */ +#define C2_SF 5.77078f /* 4/log(2) */ + +#define PE_C1 3.0f /* log(8.0)/log(2) */ +#define PE_C2 1.3219281f /* log(2.5)/log(2) */ +#define PE_C3 0.5593573f /* 1-C2/C1 */ + +#define CLIP_SAVE_LO_TO_HI_LONG (CLIP_SAVE_HI_LONG - CLIP_SAVE_LO_LONG) +#define CLIP_SAVE_LO_TO_HI_SHORT (CLIP_SAVE_HI_SHORT - CLIP_SAVE_LO_SHORT) +#define CLIP_SPEND_LO_TO_HI_LONG (CLIP_SPEND_HI_LONG - CLIP_SPEND_LO_LONG) +#define CLIP_SPEND_LO_TO_HI_SHORT (CLIP_SPEND_HI_SHORT - CLIP_SPEND_LO_SHORT) +#define MIN_TO_MAX_SAVE_BITS_LONG (MAX_BITS_SAVE_LONG - MIN_BITS_SAVE_LONG) +#define MIN_TO_MAX_SAVE_BITS_SHORT (MAX_BITS_SAVE_SHORT - MIN_BITS_SAVE_SHORT) +#define MIN_TO_MAX_SPEND_BITS_LONG (MAX_BITS_SPEND_LONG - MIN_BITS_SPEND_LONG) +#define MIN_TO_MAX_SPEND_BITS_SHORT (MAX_BITS_SPEND_SHORT - MIN_BITS_SPEND_SHORT) +#define BITS_SAVE_RATIO_LONG (MIN_TO_MAX_SAVE_BITS_LONG / CLIP_SAVE_LO_TO_HI_LONG) +#define BITS_SAVE_RATIO_SHORT (MIN_TO_MAX_SAVE_BITS_SHORT / CLIP_SAVE_LO_TO_HI_SHORT) +#define BITS_SPEND_RATIO_LONG (MIN_TO_MAX_SPEND_BITS_LONG / CLIP_SPEND_LO_TO_HI_LONG) +#define BITS_SPEND_RATIO_SHORT (MIN_TO_MAX_SPEND_BITS_SHORT / CLIP_SPEND_LO_TO_HI_SHORT) + +typedef struct { + FLOAT32 *sfb_ld_energy; + FLOAT32 *sfb_lines; + FLOAT32 sfb_pe[MAX_GROUPED_SFB_TEMP]; + FLOAT32 sfb_const_part[MAX_GROUPED_SFB_TEMP]; + FLOAT32 num_sfb_active_lines[MAX_GROUPED_SFB_TEMP]; + FLOAT32 pe; + FLOAT32 const_part; + FLOAT32 num_active_lines; +} ia_qc_pe_chan_data_struct; + +typedef struct { + ia_qc_pe_chan_data_struct pe_ch_data[30]; + FLOAT32 pe; + FLOAT32 const_part; + FLOAT32 num_active_lines; + FLOAT32 offset; +} ia_qc_pe_data_struct; + +enum ia_avoid_hole_state { NO_AH = 0, AH_INACTIVE = 1, AH_ACTIVE = 2 }; + +typedef enum { + SI_ID_BITS = (3), + SI_FILL_COUNT_BITS = (4), + SI_FILL_ESC_COUNT_BITS = (8), + SI_FILL_EXTENTION_BITS = (4), + SI_FILL_NIBBLE_BITS = (4), + SI_SCE_BITS = (4), + SI_CPE_BITS = (5), + SI_CPE_MS_MASK_BITS = (2), + SI_ICS_INFO_BITS_LONG = (1 + 2 + 6), + SI_ICS_INFO_BITS_SHORT = (1 + 2 + 4 + 7), + SI_ICS_BITS = (8 + 1 + 1 + 1), +} SI_BITS; + +FLOAT32 iusace_bits_to_pe(const FLOAT32 bits); + +VOID iusace_adj_thr_init(ia_adj_thr_elem_struct *pstr_adj_thr_state, const FLOAT32 mean_pe, + WORD32 ch_bitrate); + +IA_ERRORCODE iusace_adj_thr(ia_adj_thr_elem_struct *pstr_adj_thr_elem, + ia_psy_mod_out_data_struct *pstr_psy_out, FLOAT32 *ch_bit_dist, + ia_qc_out_data_struct *pstr_qc_out, const WORD32 avg_bits, + const WORD32 bitres_bits, const WORD32 max_bitres_bits, + const WORD32 side_info_bits, FLOAT32 *max_bit_fac, + WORD32 num_channels, WORD32 chn, iusace_scratch_mem *pstr_scratch); + +VOID iusace_calc_form_fac_per_chan(ia_psy_mod_out_data_struct *pstr_psy_out_chan, + iusace_scratch_mem *pstr_scratch, WORD32 i_ch); + +VOID iusace_estimate_scfs_chan(ia_psy_mod_out_data_struct *pstr_psy_out, + ia_qc_out_chan_struct *str_qc_out_chan, WORD32 num_channels, + WORD32 chn, iusace_scratch_mem *pstr_scratch); + +VOID iusace_quantize_lines(const WORD32 gain, const WORD32 num_lines, FLOAT32 *ptr_exp_spectrum, + WORD16 *ptr_quant_spectrum, FLOAT32 *ptr_mdct_spec); diff --git a/encoder/iusace_fd_qc_util.h b/encoder/iusace_fd_qc_util.h new file mode 100644 index 0000000..95f2ef4 --- /dev/null +++ b/encoder/iusace_fd_qc_util.h @@ -0,0 +1,74 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once + +#ifndef IXHEAACE_MAX_CH_IN_BS_ELE +#define IXHEAACE_MAX_CH_IN_BS_ELE (2) +#endif + +#define FRAME_LEN_BYTES_MODULO (1) +#define FRAME_LEN_BYTES_INT (2) + +typedef struct { + WORD32 ch_bitrate; + WORD32 avg_bits; + WORD32 max_bits; + WORD32 bit_res_lvl; + WORD32 max_bitres_bits; + WORD32 static_bits; + FLOAT32 max_bit_fac; + WORD32 tot_avg_bits; + WORD32 padding; + ia_adj_thr_state_struct str_adj_thr; + ia_adj_thr_elem_struct str_adj_thr_ele; + WORD8 num_ch; +} ia_qc_data_struct; + +typedef struct { + WORD16 quant_spec[LEN_SUPERFRAME]; + UWORD16 max_val_in_sfb[LEN_SUPERFRAME]; + WORD16 scalefactor[LEN_SUPERFRAME]; + WORD32 global_gain; +} ia_qc_out_chan_struct; + +typedef struct { + ia_qc_out_chan_struct str_qc_out_chan[IXHEAACE_MAX_CH_IN_BS_ELE]; + WORD32 static_bits; + WORD32 dyn_bits; + WORD32 fill_bits; + FLOAT32 pe; +} ia_qc_out_data_struct; + +typedef struct { + ia_qc_data_struct str_qc_data[IXHEAACE_MAX_CH_IN_BS_ELE]; + ia_qc_out_data_struct str_qc_out; +} ia_qc_main_struct; + +VOID iusace_qc_create(ia_qc_main_struct *pstr_qc_data); + +VOID iusace_qc_init(ia_qc_data_struct *pstr_qc_data, const WORD32 max_bits, WORD32 sample_rate, + WORD32 bw_limit, WORD32 channels, WORD32 ccfl); + +VOID iusace_adj_bitrate(ia_qc_data_struct *pstr_qc_data, WORD32 bit_rate, WORD32 sample_rate, + WORD32 ccfl); + +WORD32 iusace_calc_max_val_in_sfb(WORD32 sfb_count, WORD32 max_sfb_per_grp, WORD32 sfb_per_group, + WORD32 *ptr_sfb_offset, WORD16 *ptr_quant_spec); diff --git a/encoder/iusace_fd_quant.h b/encoder/iusace_fd_quant.h new file mode 100644 index 0000000..a9e434c --- /dev/null +++ b/encoder/iusace_fd_quant.h @@ -0,0 +1,35 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +#define MAX_QUANT 8192 +#define SF_OFFSET 100 + +#define sgn(A) ((A) > 0 ? (1) : (-1)) + +typedef struct ia_usac_quant_info_struct { + WORD32 scale_factor[MAX_SF_BANDS]; + WORD32 quant_degroup[FRAME_LEN_LONG]; + WORD32 arith_size_prev; + WORD32 reset; + WORD32 c_prev[(FRAME_LEN_LONG / 2) + 4]; + WORD32 c_pres[(FRAME_LEN_LONG / 2) + 4]; + WORD32 max_spec_coeffs; +} ia_usac_quant_info_struct; diff --git a/encoder/iusace_fft.c b/encoder/iusace_fft.c index a659cf9..0365f11 100644 --- a/encoder/iusace_fft.c +++ b/encoder/iusace_fft.c @@ -22,9 +22,22 @@ #include "ixheaac_type_def.h" #include "ixheaace_adjust_threshold_data.h" #include "iusace_cnst.h" +#include "iusace_block_switch_const.h" #include "iusace_rom.h" #include "iusace_bitbuffer.h" +/* DRC */ +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" +#include "impd_drc_uni_drc_eq.h" +#include "impd_drc_uni_drc_filter_bank.h" +#include "impd_drc_gain_enc.h" +#include "impd_drc_struct_def.h" + +#include "iusace_tns_usac.h" +#include "iusace_psy_mod.h" #include "iusace_config.h" #include "iusace_fft.h" #include "iusace_basic_ops_flt.h" @@ -798,6 +811,42 @@ VOID iusace_complex_fft_p3_no_scratch(FLOAT32 *data, WORD32 nlength) { } } +static VOID iusace_calc_pre_twid_enc(FLOAT64 *ptr_in, FLOAT32 *fft_ptr, WORD32 npoints, + const FLOAT64 *cos_ptr, const FLOAT64 *sin_ptr, + const WORD32 tx_flag) { + WORD32 i, n; + WORD32 b = npoints >> 1; + WORD32 a = npoints - b; + WORD32 nlength = npoints >> 2; + FLOAT64 tempr, tempi; + + if (tx_flag == 0) { + FLOAT64 norm; + for (i = 0; i < b; i++) { + norm = ptr_in[i]; /* reuse MDCT: spectrally reverse all bins */ + ptr_in[i] = ptr_in[npoints - 1 - i]; + ptr_in[npoints - 1 - i] = norm; + } + } + for (i = 0; i < nlength; i++) { + n = npoints / 2 - 1 - 2 * i; + if (i < b / 4) { + tempr = ptr_in[a / 2 + n] + ptr_in[npoints + a / 2 - 1 - n]; + } else { + tempr = ptr_in[a / 2 + n] - ptr_in[a / 2 - 1 - n]; + } + n = 2 * i; + if (i < a / 4) { + tempi = ptr_in[a / 2 + n] - ptr_in[a / 2 - 1 - n]; + } else { + tempi = ptr_in[a / 2 + n] + ptr_in[npoints + a / 2 - 1 - n]; + } + + fft_ptr[2 * i] = (FLOAT32)(tempr * (*cos_ptr) + tempi * (*sin_ptr)); + fft_ptr[2 * i + 1] = (FLOAT32)(tempi * (*cos_ptr++) - tempr * (*sin_ptr++)); + } +} + VOID iusace_complex_fft(FLOAT32 *data, WORD32 nlength, iusace_scratch_mem *pstr_scratch) { if (nlength & (nlength - 1)) { iusace_complex_fft_p3(data, nlength, pstr_scratch); @@ -806,6 +855,75 @@ VOID iusace_complex_fft(FLOAT32 *data, WORD32 nlength, iusace_scratch_mem *pstr_ } } +static VOID iusace_calc_post_twid_enc(FLOAT64 *ptr_out, FLOAT32 *fft_ptr, WORD32 npoints, + const FLOAT64 *cos_ptr, const FLOAT64 *sin_ptr, + const WORD32 tx_flag) { + WORD32 i; + WORD32 nlength = npoints >> 2; + FLOAT64 tempr, tempi; + + /* post-twiddle FFT output and then get output data */ + for (i = 0; i < nlength; i++) { + tempr = + 2 * ((FLOAT64)(fft_ptr[2 * i]) * (*cos_ptr) + (FLOAT64)(fft_ptr[2 * i + 1]) * (*sin_ptr)); + tempi = 2 * ((FLOAT64)(fft_ptr[2 * i + 1]) * (*cos_ptr++) - + (FLOAT64)(fft_ptr[2 * i]) * (*sin_ptr++)); + + ptr_out[2 * i] = -tempr; + ptr_out[npoints / 2 - 1 - 2 * i] = tempi; + ptr_out[npoints / 2 + 2 * i] = -tempi; + ptr_out[npoints - 1 - 2 * i] = tempr; + } + if (tx_flag == 0) { + for (i = 0; i < npoints; i += 2) { + ptr_out[i] *= -1; /* reuse MDCT: flip signs at odd indices */ + } + } +} + +IA_ERRORCODE iusace_fft_based_mdct(FLOAT64 *ptr_in, FLOAT64 *ptr_out, WORD32 npoints, + const WORD32 tx_flag, iusace_scratch_mem *pstr_scratch) { + FLOAT32 *ptr_scratch1 = pstr_scratch->p_fft_mdct_buf; + const FLOAT64 *cos_ptr = NULL; + const FLOAT64 *sin_ptr = NULL; + WORD32 nlength = npoints >> 1; + WORD32 n_total = npoints << 1; + + memset(ptr_scratch1, 0, ((SIZE_T)n_total << 1) * sizeof(*ptr_scratch1)); + + switch (npoints) { + case (96): + cos_ptr = iexheaac_pre_post_twid_cos_192; + sin_ptr = iexheaac_pre_post_twid_sin_192; + break; + case (128): + cos_ptr = iusace_pre_post_twid_cos_256; + sin_ptr = iusace_pre_post_twid_sin_256; + break; + case (768): + cos_ptr = iexheaac_pre_post_twid_cos_1536; + sin_ptr = iexheaac_pre_post_twid_sin_1536; + break; + case (1024): + cos_ptr = iusace_pre_post_twid_cos_2048; + sin_ptr = iusace_pre_post_twid_sin_2048; + break; + default: + return -1; + } + + /* pre-twiddle */ + iusace_calc_pre_twid_enc(ptr_in, ptr_scratch1, npoints << 1, cos_ptr, sin_ptr, tx_flag); + + /* complex FFT */ + iusace_complex_fft(ptr_scratch1, nlength, pstr_scratch); + + /* post-twiddle */ + iusace_calc_post_twid_enc(ptr_out, ptr_scratch1, npoints << 1, cos_ptr, sin_ptr, tx_flag); + + return 0; +} + VOID iusace_complex_fft_2048(FLOAT32 *ptr_x, FLOAT32 *scratch_fft) { WORD32 i; FLOAT32 re, im, c_v, s_v, tmp_re, tmp_im; @@ -841,3 +959,626 @@ VOID iusace_complex_fft_2048(FLOAT32 *ptr_x, FLOAT32 *scratch_fft) { ptr_im_h += 2; } } +static VOID ixheaace_rad2_cplx_fft(FLOAT32 *ptr_real, FLOAT32 *ptr_imag, WORD32 n_points, + FLOAT32 *ptr_scratch) { + WORD32 i, j, k, n_stages, h2; + FLOAT32 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + WORD32 del, nodespacing, in_loop_cnt; + WORD32 not_power_4; + WORD32 dig_rev_shift; + WORD32 m_points = n_points; + FLOAT32 *ptr_x = ptr_scratch; + FLOAT32 *y = ptr_scratch + 2048; + FLOAT32 *ptr_y = y; + const FLOAT32 *ptr_w; + + dig_rev_shift = ixheaac_norm32(m_points) + 1 - 16; + n_stages = 30 - ixheaac_norm32(m_points); + not_power_4 = n_stages & 1; + + n_stages = n_stages >> 1; + + ptr_w = ia_fft_twiddle_table_float; + + for (i = 0; i < n_points; i++) { + ptr_x[2 * i] = ptr_real[i]; + ptr_x[2 * i + 1] = ptr_imag[i]; + } + dig_rev_shift = max(dig_rev_shift, 0); + for (i = 0; i < n_points; i += 4) { + FLOAT32 *inp = ptr_x; + FLOAT32 tmk; + + DIG_REV(i, dig_rev_shift, h2); + if (not_power_4) { + h2 += 1; + h2 &= ~1; + } + inp += (h2); + + x0r = *inp; + x0i = *(inp + 1); + inp += (n_points >> 1); + + x1r = *inp; + x1i = *(inp + 1); + inp += (n_points >> 1); + + x2r = *inp; + x2i = *(inp + 1); + inp += (n_points >> 1); + + x3r = *inp; + x3i = *(inp + 1); + + x0r = ia_add_flt(x0r, x2r); + x0i = ia_add_flt(x0i, x2i); + + tmk = ia_sub_flt(x0r, x2r); + x2r = ia_sub_flt(tmk, x2r); + tmk = ia_sub_flt(x0i, x2i); + x2i = ia_sub_flt(tmk, x2i); + + x1r = ia_add_flt(x1r, x3r); + x1i = ia_add_flt(x1i, x3i); + + tmk = ia_sub_flt(x1r, x3r); + x3r = ia_sub_flt(tmk, x3r); + tmk = ia_sub_flt(x1i, x3i); + x3i = ia_sub_flt(tmk, x3i); + + x0r = ia_add_flt(x0r, x1r); + x0i = ia_add_flt(x0i, x1i); + + tmk = ia_sub_flt(x0r, x1r); + x1r = ia_sub_flt(tmk, x1r); + tmk = ia_sub_flt(x0i, x1i); + x1i = ia_sub_flt(tmk, x1i); + + x2r = ia_add_flt(x2r, x3i); + x2i = ia_sub_flt(x2i, x3r); + + tmk = ia_sub_flt(x2r, x3i); + x3i = ia_sub_flt(tmk, x3i); + tmk = ia_add_flt(x2i, x3r); + x3r = ia_add_flt(tmk, x3r); + + *ptr_y++ = x0r; + *ptr_y++ = x0i; + *ptr_y++ = x2r; + *ptr_y++ = x2i; + *ptr_y++ = x1r; + *ptr_y++ = x1i; + *ptr_y++ = x3i; + *ptr_y++ = x3r; + } + ptr_y -= 2 * n_points; + del = 4; + nodespacing = 64; + in_loop_cnt = n_points >> 4; + for (i = n_stages - 1; i > 0; i--) { + const FLOAT32 *twiddles = ptr_w; + FLOAT32 *data = ptr_y; + FLOAT32 w_1, w_2, w_3, w_4, w_5, w_6; + WORD32 sec_loop_cnt; + + for (k = in_loop_cnt; k != 0; k--) { + x0r = (*data); + x0i = (*(data + 1)); + data += ((SIZE_T)del << 1); + + x1r = (*data); + x1i = (*(data + 1)); + data += ((SIZE_T)del << 1); + + x2r = (*data); + x2i = (*(data + 1)); + data += ((SIZE_T)del << 1); + + x3r = (*data); + x3i = (*(data + 1)); + data -= 3 * (del << 1); + + x0r = ia_add_flt(x0r, x2r); + x0i = ia_add_flt(x0i, x2i); + x2r = ia_msu_flt(x0r, x2r, 2); + x2i = ia_msu_flt(x0i, x2i, 2); + x1r = ia_add_flt(x1r, x3r); + x1i = ia_add_flt(x1i, x3i); + x3r = ia_msu_flt(x1r, x3r, 2); + x3i = ia_msu_flt(x1i, x3i, 2); + + x0r = ia_add_flt(x0r, x1r); + x0i = ia_add_flt(x0i, x1i); + x1r = ia_msu_flt(x0r, x1r, 2); + x1i = ia_msu_flt(x0i, x1i, 2); + x2r = ia_add_flt(x2r, x3i); + x2i = ia_sub_flt(x2i, x3r); + x3i = ia_msu_flt(x2r, x3i, 2); + x3r = ia_mac_flt(x2i, x3r, 2); + + *data = x0r; + *(data + 1) = x0i; + data += ((SIZE_T)del << 1); + + *data = x2r; + *(data + 1) = x2i; + data += ((SIZE_T)del << 1); + + *data = x1r; + *(data + 1) = x1i; + data += ((SIZE_T)del << 1); + + *data = x3i; + *(data + 1) = x3r; + data += ((SIZE_T)del << 1); + } + data = ptr_y + 2; + + sec_loop_cnt = (nodespacing * del); + sec_loop_cnt = (sec_loop_cnt / 4) + (sec_loop_cnt / 8) - (sec_loop_cnt / 16) + + (sec_loop_cnt / 32) - (sec_loop_cnt / 64) + (sec_loop_cnt / 128) - + (sec_loop_cnt / 256); + + for (j = nodespacing; j <= sec_loop_cnt; j += nodespacing) { + w_1 = *(twiddles + j); + w_4 = *(twiddles + j + 257); + w_2 = *(twiddles + ((SIZE_T)j << 1)); + w_5 = *(twiddles + ((SIZE_T)j << 1) + 257); + w_3 = *(twiddles + j + ((SIZE_T)j << 1)); + w_6 = *(twiddles + j + ((SIZE_T)j << 1) + 257); + + for (k = in_loop_cnt; k != 0; k--) { + FLOAT32 tmp; + /*x0 is loaded later to avoid register crunch*/ + + data += ((SIZE_T)del << 1); + + x1r = *data; + x1i = *(data + 1); + data += ((SIZE_T)del << 1); + + x2r = *data; + x2i = *(data + 1); + data += ((SIZE_T)del << 1); + + x3r = *data; + x3i = *(data + 1); + data -= 3 * (del << 1); + + tmp = ia_sub_flt(ia_mul_flt(x1r, w_1), ia_mul_flt(x1i, w_4)); + x1i = ia_mac_flt(ia_mul_flt(x1r, w_4), x1i, w_1); + x1r = tmp; + + tmp = ia_sub_flt(ia_mul_flt(x2r, w_2), ia_mul_flt(x2i, w_5)); + x2i = ia_mac_flt(ia_mul_flt(x2r, w_5), x2i, w_2); + x2r = tmp; + + tmp = ia_sub_flt(ia_mul_flt(x3r, w_3), ia_mul_flt(x3i, w_6)); + x3i = ia_mac_flt(ia_mul_flt(x3r, w_6), x3i, w_3); + x3r = tmp; + + x0r = (*data); + x0i = (*(data + 1)); + + x0r = ia_add_flt(x0r, (x2r)); + x0i = ia_add_flt(x0i, (x2i)); + x2r = ia_msu_flt(x0r, x2r, 2); + x2i = ia_msu_flt(x0i, x2i, 2); + x1r = ia_add_flt(x1r, x3r); + x1i = ia_add_flt(x1i, x3i); + x3r = ia_msu_flt(x1r, x3r, 2); + x3i = ia_msu_flt(x1i, x3i, 2); + + x0r = ia_add_flt(x0r, (x1r)); + x0i = ia_add_flt(x0i, (x1i)); + x1r = ia_msu_flt(x0r, x1r, 2); + x1i = ia_msu_flt(x0i, x1i, 2); + x2r = ia_add_flt(x2r, (x3i)); + x2i = ia_sub_flt(x2i, (x3r)); + x3i = ia_msu_flt(x2r, x3i, 2); + x3r = ia_mac_flt(x2i, x3r, 2); + + *data = x0r; + *(data + 1) = x0i; + data += ((SIZE_T)del << 1); + + *data = x2r; + *(data + 1) = x2i; + data += ((SIZE_T)del << 1); + + *data = x1r; + *(data + 1) = x1i; + data += ((SIZE_T)del << 1); + + *data = x3i; + *(data + 1) = x3r; + data += ((SIZE_T)del << 1); + } + data -= 2 * n_points; + data += 2; + } + for (; j <= (nodespacing * del) >> 1; j += nodespacing) { + w_1 = *(twiddles + j); + w_4 = *(twiddles + j + 257); + w_2 = *(twiddles + ((SIZE_T)j << 1)); + w_5 = *(twiddles + ((SIZE_T)j << 1) + 257); + w_3 = *(twiddles + j + ((SIZE_T)j << 1) - 256); + w_6 = *(twiddles + j + ((SIZE_T)j << 1) + 1); + + for (k = in_loop_cnt; k != 0; k--) { + FLOAT32 tmp; + /*x0 is loaded later to avoid register crunch*/ + + data += ((SIZE_T)del << 1); + + x1r = *data; + x1i = *(data + 1); + data += ((SIZE_T)del << 1); + + x2r = *data; + x2i = *(data + 1); + data += ((SIZE_T)del << 1); + + x3r = *data; + x3i = *(data + 1); + data -= 3 * (del << 1); + + tmp = ia_sub_flt(ia_mul_flt(x1r, w_1), ia_mul_flt(x1i, w_4)); + x1i = ia_mac_flt(ia_mul_flt(x1r, w_4), x1i, w_1); + x1r = tmp; + + tmp = ia_sub_flt(ia_mul_flt(x2r, w_2), ia_mul_flt(x2i, w_5)); + x2i = ia_mac_flt(ia_mul_flt(x2r, w_5), x2i, w_2); + x2r = tmp; + + tmp = ia_add_flt(ia_mul_flt(x3r, w_6), ia_mul_flt(x3i, w_3)); + x3i = ia_add_flt(ia_negate_flt(ia_mul_flt(x3r, w_3)), ia_mul_flt(x3i, w_6)); + x3r = tmp; + + x0r = (*data); + x0i = (*(data + 1)); + + x0r = ia_add_flt(x0r, (x2r)); + x0i = ia_add_flt(x0i, (x2i)); + x2r = ia_msu_flt(x0r, x2r, 2); + x2i = ia_msu_flt(x0i, x2i, 2); + x1r = ia_add_flt(x1r, x3r); + x1i = ia_add_flt(x1i, x3i); + x3r = ia_msu_flt(x1r, x3r, 2); + x3i = ia_msu_flt(x1i, x3i, 2); + + x0r = ia_add_flt(x0r, (x1r)); + x0i = ia_add_flt(x0i, (x1i)); + x1r = ia_msu_flt(x0r, x1r, 2); + x1i = ia_msu_flt(x0i, x1i, 2); + x2r = ia_add_flt(x2r, (x3i)); + x2i = ia_sub_flt(x2i, (x3r)); + x3i = ia_msu_flt(x2r, x3i, 2); + x3r = ia_mac_flt(x2i, x3r, 2); + + *data = x0r; + *(data + 1) = x0i; + data += ((SIZE_T)del << 1); + + *data = x2r; + *(data + 1) = x2i; + data += ((SIZE_T)del << 1); + + *data = x1r; + *(data + 1) = x1i; + data += ((SIZE_T)del << 1); + + *data = x3i; + *(data + 1) = x3r; + data += ((SIZE_T)del << 1); + } + data -= 2 * n_points; + data += 2; + } + for (; j <= sec_loop_cnt * 2; j += nodespacing) { + w_1 = *(twiddles + j); + w_4 = *(twiddles + j + 257); + w_2 = *(twiddles + ((SIZE_T)j << 1) - 256); + w_5 = *(twiddles + ((SIZE_T)j << 1) + 1); + w_3 = *(twiddles + j + ((SIZE_T)j << 1) - 256); + w_6 = *(twiddles + j + ((SIZE_T)j << 1) + 1); + + for (k = in_loop_cnt; k != 0; k--) { + FLOAT32 tmp; + /*x0 is loaded later to avoid register crunch*/ + + data += ((SIZE_T)del << 1); + + x1r = *data; + x1i = *(data + 1); + data += ((SIZE_T)del << 1); + + x2r = *data; + x2i = *(data + 1); + data += ((SIZE_T)del << 1); + + x3r = *data; + x3i = *(data + 1); + data -= 3 * (del << 1); + + tmp = ia_sub_flt(ia_mul_flt(x1r, w_1), ia_mul_flt(x1i, w_4)); + x1i = ia_mac_flt(ia_mul_flt(x1r, w_4), x1i, w_1); + x1r = tmp; + + tmp = ia_add_flt(ia_mul_flt(x2r, w_5), ia_mul_flt(x2i, w_2)); + x2i = ia_add_flt(ia_negate_flt(ia_mul_flt(x2r, w_2)), ia_mul_flt(x2i, w_5)); + x2r = tmp; + + tmp = ia_add_flt(ia_mul_flt(x3r, w_6), ia_mul_flt(x3i, w_3)); + x3i = ia_add_flt(ia_negate_flt(ia_mul_flt(x3r, w_3)), ia_mul_flt(x3i, w_6)); + x3r = tmp; + + x0r = (*data); + x0i = (*(data + 1)); + + x0r = ia_add_flt(x0r, (x2r)); + x0i = ia_add_flt(x0i, (x2i)); + x2r = ia_msu_flt(x0r, x2r, 2); + x2i = ia_msu_flt(x0i, x2i, 2); + x1r = ia_add_flt(x1r, x3r); + x1i = ia_add_flt(x1i, x3i); + x3r = ia_msu_flt(x1r, x3r, 2); + x3i = ia_msu_flt(x1i, x3i, 2); + + x0r = ia_add_flt(x0r, (x1r)); + x0i = ia_add_flt(x0i, (x1i)); + x1r = ia_msu_flt(x0r, x1r, 2); + x1i = ia_msu_flt(x0i, x1i, 2); + x2r = ia_add_flt(x2r, (x3i)); + x2i = ia_sub_flt(x2i, (x3r)); + x3i = ia_msu_flt(x2r, x3i, 2); + x3r = ia_mac_flt(x2i, x3r, 2); + + *data = x0r; + *(data + 1) = x0i; + data += ((SIZE_T)del << 1); + + *data = x2r; + *(data + 1) = x2i; + data += ((SIZE_T)del << 1); + + *data = x1r; + *(data + 1) = x1i; + data += ((SIZE_T)del << 1); + + *data = x3i; + *(data + 1) = x3r; + data += ((SIZE_T)del << 1); + } + data -= 2 * n_points; + data += 2; + } + for (; j < nodespacing * del; j += nodespacing) { + w_1 = *(twiddles + j); + w_4 = *(twiddles + j + 257); + w_2 = *(twiddles + ((SIZE_T)j << 1) - 256); + w_5 = *(twiddles + ((SIZE_T)j << 1) + 1); + w_3 = *(twiddles + j + ((SIZE_T)j << 1) - 512); + w_6 = *(twiddles + j + ((SIZE_T)j << 1) - 512 + 257); + + for (k = in_loop_cnt; k != 0; k--) { + FLOAT32 tmp; + /*x0 is loaded later to avoid register crunch*/ + + data += ((SIZE_T)del << 1); + + x1r = *data; + x1i = *(data + 1); + data += ((SIZE_T)del << 1); + + x2r = *data; + x2i = *(data + 1); + data += ((SIZE_T)del << 1); + + x3r = *data; + x3i = *(data + 1); + data -= 3 * (del << 1); + + tmp = ia_sub_flt(ia_mul_flt(x1r, w_1), ia_mul_flt(x1i, w_4)); + x1i = ia_mac_flt(ia_mul_flt(x1r, w_4), x1i, w_1); + x1r = tmp; + + tmp = ia_add_flt(ia_mul_flt(x2r, w_5), ia_mul_flt(x2i, w_2)); + x2i = ia_add_flt(ia_negate_flt(ia_mul_flt(x2r, w_2)), ia_mul_flt(x2i, w_5)); + x2r = tmp; + + tmp = ia_add_flt(ia_negate_flt(ia_mul_flt(x3r, w_3)), ia_mul_flt(x3i, w_6)); + x3i = ia_mac_flt(ia_mul_flt(x3r, w_6), x3i, w_3); + x3r = tmp; + + x0r = (*data); + x0i = (*(data + 1)); + + x0r = ia_add_flt(x0r, (x2r)); + x0i = ia_add_flt(x0i, (x2i)); + x2r = ia_msu_flt(x0r, x2r, 2); + x2i = ia_msu_flt(x0i, x2i, 2); + x1r = ia_add_flt(x1r, x3r); + x1i = ia_sub_flt(x1i, x3i); + x3r = ia_msu_flt(x1r, x3r, 2); + x3i = ia_mac_flt(x1i, x3i, 2); + + x0r = ia_add_flt(x0r, (x1r)); + x0i = ia_add_flt(x0i, (x1i)); + x1r = ia_msu_flt(x0r, x1r, 2); + x1i = ia_msu_flt(x0i, x1i, 2); + x2r = ia_add_flt(x2r, (x3i)); + x2i = ia_sub_flt(x2i, (x3r)); + x3i = ia_msu_flt(x2r, x3i, 2); + x3r = ia_mac_flt(x2i, x3r, 2); + + *data = x0r; + *(data + 1) = x0i; + data += ((SIZE_T)del << 1); + + *data = x2r; + *(data + 1) = x2i; + data += ((SIZE_T)del << 1); + + *data = x1r; + *(data + 1) = x1i; + data += ((SIZE_T)del << 1); + + *data = x3i; + *(data + 1) = x3r; + data += ((SIZE_T)del << 1); + } + data -= 2 * n_points; + data += 2; + } + nodespacing >>= 2; + del <<= 2; + in_loop_cnt >>= 2; + } + if (not_power_4) { + const FLOAT32 *twiddles = ptr_w; + nodespacing <<= 1; + + for (j = del / 2; j != 0; j--) { + FLOAT32 w_1 = *twiddles; + FLOAT32 w_4 = *(twiddles + 257); + FLOAT32 tmp; + twiddles += nodespacing; + + x0r = *ptr_y; + x0i = *(ptr_y + 1); + ptr_y += ((SIZE_T)del << 1); + + x1r = *ptr_y; + x1i = *(ptr_y + 1); + + tmp = ia_sub_flt(ia_mul_flt(x1r, w_1), ia_mul_flt(x1i, w_4)); + x1i = (FLOAT32)ia_mac_flt(ia_mul_flt(x1r, w_4), x1i, w_1); + x1r = tmp; + + *ptr_y = ia_sub_flt((x0r), (x1r)); + *(ptr_y + 1) = ia_sub_flt((x0i), (x1i)); + ptr_y -= ((SIZE_T)del << 1); + + *ptr_y = ia_add_flt((x0r), (x1r)); + *(ptr_y + 1) = ia_add_flt((x0i), (x1i)); + ptr_y += 2; + } + twiddles = ptr_w; + for (j = del / 2; j != 0; j--) { + FLOAT32 w_1 = *twiddles; + FLOAT32 w_4 = *(twiddles + 257); + FLOAT32 tmp; + twiddles += nodespacing; + + x0r = *ptr_y; + x0i = *(ptr_y + 1); + ptr_y += ((SIZE_T)del << 1); + + x1r = *ptr_y; + x1i = *(ptr_y + 1); + + tmp = ia_add_flt(ia_mul_flt(x1r, w_4), ia_mul_flt(x1i, w_1)); + x1i = ia_add_flt(ia_negate_flt(ia_mul_flt(x1r, w_1)), ia_mul_flt(x1i, w_4)); + x1r = tmp; + + *ptr_y = ia_sub_flt((x0r), (x1r)); + *(ptr_y + 1) = ia_sub_flt((x0i), (x1i)); + ptr_y -= ((SIZE_T)del << 1); + + *ptr_y = ia_add_flt((x0r), (x1r)); + *(ptr_y + 1) = ia_add_flt((x0i), (x1i)); + ptr_y += 2; + } + } + + for (i = 0; i < n_points; i++) { + ptr_real[i] = y[2 * i]; + ptr_imag[i] = y[2 * i + 1]; + } +} +static VOID ixheaace_cplx_fft_4(FLOAT32 *x_r, FLOAT32 *x_i) { + FLOAT32 x_0, x_1, x_2, x_3; + FLOAT32 x_4, x_5, x_6, x_7; + FLOAT32 x0r, x1r, x2r, x3r; + FLOAT32 x0i, x1i, x2i, x3i; + + // 4 Point FFT + x_0 = x_r[0]; + x_1 = x_i[0]; + x_2 = x_r[1]; + x_3 = x_i[1]; + x_4 = x_r[2]; + x_5 = x_i[2]; + x_6 = x_r[3]; + x_7 = x_i[3]; + + x0r = ia_add_flt(x_0, x_4); + x0i = ia_add_flt(x_1, x_5); + x2r = ia_sub_flt(x_0, x_4); + x2i = ia_sub_flt(x_1, x_5); + x1r = ia_add_flt(x_2, x_6); + x1i = ia_add_flt(x_3, x_7); + x3r = ia_sub_flt(x_2, x_6); + x3i = ia_sub_flt(x_3, x_7); + + x_r[0] = ia_add_flt(x0r, x1r); + x_i[0] = ia_add_flt(x0i, x1i); + x_r[2] = ia_sub_flt(x0r, x1r); + x_i[2] = ia_sub_flt(x0i, x1i); + x_r[1] = ia_add_flt(x2r, x3i); + x_i[1] = ia_sub_flt(x2i, x3r); + x_r[3] = ia_sub_flt(x2r, x3i); + x_i[3] = ia_add_flt(x2i, x3r); + return; +} +VOID iusace_complex_fft_4096(FLOAT32 *ptr_x_r, FLOAT32 *ptr_x_i, FLOAT32 *ptr_scratch_buf) { + FLOAT32 *ptr_data_r; + FLOAT32 *ptr_data_i; + WORD32 fft_len = 4096; + FLOAT32 *ptr_fft_interim_buf = &ptr_scratch_buf[2 * fft_len]; + WORD32 i, j; + WORD32 dim2 = fft_len >> 10; + WORD32 dim1 = fft_len / dim2; + WORD32 fac = 4; + + for (i = 0; i < dim2; i++) { + ptr_data_r = &ptr_scratch_buf[(2 * i + 0) * dim1]; + ptr_data_i = &ptr_scratch_buf[(2 * i + 1) * dim1]; + for (j = 0; j < dim1; j++) { + ptr_data_r[j] = ptr_x_r[(dim2 * j + i)]; + ptr_data_i[j] = 0; + } + ixheaace_rad2_cplx_fft(ptr_data_r, ptr_data_i, dim1, ptr_fft_interim_buf); + } + ptr_data_r = &ptr_scratch_buf[0]; + ptr_data_i = &ptr_scratch_buf[0]; + for (i = 0; i < dim1; i++) { + FLOAT32 *ptr_cos_val = (FLOAT32 *)&ia_mixed_rad_twiddle_cos[i * dim2 * fac]; + FLOAT32 *ptr_sin_val = (FLOAT32 *)&ia_mixed_rad_twiddle_sin[i * dim2 * fac]; + for (j = 0; j < dim2; j++) { + FLOAT32 real = ptr_data_r[(2 * j + 0) * dim1 + i]; + FLOAT32 imag = ptr_data_i[(2 * j + 1) * dim1 + i]; + FLOAT32 cos_val = ptr_cos_val[j * fac]; + FLOAT32 sin_val = ptr_sin_val[j * fac]; + FLOAT32 temp_real = (FLOAT32)(real * cos_val + imag * sin_val); + FLOAT32 temp_imag = (FLOAT32)(imag * cos_val - real * sin_val); + ptr_fft_interim_buf[(2 * i + 0) * dim2 + j] = temp_real; + ptr_fft_interim_buf[(2 * i + 1) * dim2 + j] = temp_imag; + } + } + for (i = 0; i < dim1; i++) { + ptr_data_r = &ptr_fft_interim_buf[(2 * i + 0) * dim2]; + ptr_data_i = &ptr_fft_interim_buf[(2 * i + 1) * dim2]; + ixheaace_cplx_fft_4(ptr_data_r, ptr_data_i); + } + ptr_data_r = &ptr_fft_interim_buf[0]; + ptr_data_i = &ptr_fft_interim_buf[0]; + for (i = 0; i < dim1; i++) { + for (j = 0; j < dim2; j++) { + ptr_x_r[(j * dim1 + i)] = ptr_data_r[(2 * i + 0) * dim2 + j]; + ptr_x_i[(j * dim1 + i)] = ptr_data_i[(2 * i + 1) * dim2 + j]; + } + } +} \ No newline at end of file diff --git a/encoder/iusace_fft.h b/encoder/iusace_fft.h index e846a11..8316e26 100644 --- a/encoder/iusace_fft.h +++ b/encoder/iusace_fft.h @@ -34,3 +34,8 @@ re = ((a * c) - (b * d)); \ im = ((a * d) + (b * c)); \ } + +IA_ERRORCODE iusace_fft_based_mdct(FLOAT64 *ptr_in, FLOAT64 *ptr_out, WORD32 npoints, + const WORD32 tx_flag, iusace_scratch_mem *pstr_scratch); + +VOID iusace_complex_fft(FLOAT32 *data, WORD32 nlength, iusace_scratch_mem *pstr_scratch); diff --git a/encoder/iusace_func_prototypes.h b/encoder/iusace_func_prototypes.h new file mode 100644 index 0000000..220bdf0 --- /dev/null +++ b/encoder/iusace_func_prototypes.h @@ -0,0 +1,81 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +VOID iusace_write_bits2buf(WORD32 value, WORD32 no_of_bits, WORD16 *bitstream); + +WORD32 iusace_get_num_params(WORD32 *qn); + +VOID iusace_highpass_50hz_12k8(FLOAT32 *signal, WORD32 lg, FLOAT32 *mem, WORD32 fscale); + +IA_ERRORCODE iusace_lpd_frm_enc(ia_usac_data_struct *usac_data, WORD32 *mod_out, + WORD32 const usac_independency_flg, + WORD32 len_frame, + WORD32 i_ch, ia_bit_buf_struct *pstr_it_bit_buff); + +VOID iusace_init_td_data(ia_usac_td_encoder_struct *st, WORD32 len_frame); + +VOID iusace_config_acelp_core_mode(ia_usac_td_encoder_struct *st, WORD32 sampling_rate, + WORD32 bitrate); + +VOID iusace_reset_td_enc(ia_usac_td_encoder_struct *st); + +VOID iusace_core_lpd_encode(ia_usac_data_struct *usac_data, FLOAT32 *speech, WORD32 *mode, + WORD32 *num_tcx_param, WORD32 ch_idx); + +VOID iusace_encode_fac_params(WORD32 *mod, WORD32 *n_param_tcx, ia_usac_data_struct *usac_data, + WORD32 const usac_independency_flag, + ia_bit_buf_struct *pstr_it_bit_buff, WORD32 ch_idx); + +VOID iusace_acelp_encode(FLOAT32 *lp_filt_coeff, FLOAT32 *quant_lp_filt_coeff, FLOAT32 *speech_in, + FLOAT32 *wsig_in, FLOAT32 *synth_out, FLOAT32 *wsynth_out, + WORD16 acelp_core_mode, ia_usac_lpd_state_struct *lpd_state, + WORD32 len_subfrm, FLOAT32 norm_corr, FLOAT32 norm_corr2, + WORD32 ol_pitch_lag1, WORD32 ol_pitch_lag2, WORD32 pit_adj, + WORD32 *acelp_params, iusace_scratch_mem *pstr_scratch); + +VOID iusace_tcx_fac_encode(ia_usac_data_struct *usac_data, FLOAT32 *lpc_coeffs, + FLOAT32 *lpc_coeffs_quant, FLOAT32 *speech, WORD32 frame_len, + WORD32 num_bits_per_supfrm, ia_usac_lpd_state_struct *lpd_state, + WORD32 *params, WORD32 *n_param, WORD32 ch_idx, WORD32 k_idx); + +VOID iusace_fac_apply(FLOAT32 *orig, WORD32 len_subfrm, WORD32 fac_len, WORD32 low_pass_line, + WORD32 target_br, FLOAT32 *synth, FLOAT32 *ptr_lpc_coeffs, + WORD16 *fac_bits_word, WORD32 *num_fac_bits, + iusace_scratch_mem *pstr_scratch); + +VOID iusace_quantize_lpc_avq(FLOAT32 *ptr_lsf, FLOAT32 *ptr_lsfq, WORD32 lpc0, + WORD32 *ptr_lpc_idx, WORD32 *nb_indices, WORD32 *nbbits); + +VOID iusace_lsp_2_lsf_conversion(FLOAT32 *lsp, FLOAT32 *lsf); +VOID iusace_lsp_to_lp_conversion(FLOAT32 *lsp, FLOAT32 *lp_flt_coff_a); + +VOID iusace_find_weighted_speech(FLOAT32 *filter_coef, FLOAT32 *speech, FLOAT32 *wsp, + FLOAT32 *mem_wsp, WORD32 length); + +IA_ERRORCODE iusace_fd_fac(WORD32 *sfb_offsets, WORD32 sfb_active, FLOAT64 *orig_sig_dbl, + WORD32 window_sequence, FLOAT64 *synth_time, + ia_usac_td_encoder_struct *pstr_acelp, WORD32 last_subfr_was_acelp, + WORD32 next_frm_lpd, WORD16 *fac_prm_out, WORD32 *num_fac_bits, + iusace_scratch_mem *pstr_scratch); + +FLOAT32 iusace_cal_segsnr(FLOAT32 *sig1, FLOAT32 *sig2, WORD16 len, WORD16 nseg); + +WORD32 iusace_fd_encode_fac(WORD32 *prm, WORD16 *ptr_bit_buf, WORD32 fac_length); diff --git a/encoder/iusace_lpc.c b/encoder/iusace_lpc.c new file mode 100644 index 0000000..aff6b03 --- /dev/null +++ b/encoder/iusace_lpc.c @@ -0,0 +1,216 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include "ixheaac_type_def.h" +#include "iusace_bitbuffer.h" +#include "iusace_cnst.h" +#include "iusace_tns_usac.h" +#include "iusace_psy_mod.h" +#include "iusace_block_switch_const.h" +#include "iusace_rom.h" + +static FLOAT32 iusace_lpc_eval_chebyshev_polyn(FLOAT32 x, FLOAT32 *coefs, WORD32 order) { + WORD32 i; + FLOAT32 b0, b1, b2, x2; + x2 = 2.0f * x; + b2 = 1.0f; + b1 = x2 + coefs[1]; + for (i = 2; i < order; i++) { + b0 = x2 * b1 - b2 + coefs[i]; + b2 = b1; + b1 = b0; + } + return (x * b1 - b2 + 0.5f * coefs[order]); +} + +VOID iusace_lpc_2_lsp_conversion(FLOAT32 *lpc, FLOAT32 *lsp, FLOAT32 *prev_lsp) { + FLOAT32 sum_polyn[(ORDER_BY_2) + 1], diff_polyn[(ORDER_BY_2) + 1]; + FLOAT32 *p1_lpc, *p2_lpc, *p_sum_polyn, *p_diff_polyn; + WORD32 i, j = 0, num_found_freeq = 0, is_first_polyn = 0; + FLOAT32 x_low, y_low, x_high, y_high, x_mid, y_mid, x_lin_interp; + + p_sum_polyn = sum_polyn; + p_diff_polyn = diff_polyn; + *p_sum_polyn++ = 1.0f; + *p_diff_polyn++ = 1.0f; + sum_polyn[0] = 1.0f; + diff_polyn[0] = 1.0f; + p1_lpc = lpc + 1; + p2_lpc = lpc + ORDER; + for (i = 0; i <= ORDER_BY_2 - 1; i++) { + *p_sum_polyn = *p1_lpc + *p2_lpc - *(p_sum_polyn - 1); + p_sum_polyn++; + *p_diff_polyn = *p1_lpc++ - *p2_lpc-- + *(p_diff_polyn - 1); + p_diff_polyn++; + } + p_sum_polyn = sum_polyn; + x_low = iusace_chebyshev_polyn_grid[0]; + y_low = iusace_lpc_eval_chebyshev_polyn(x_low, p_sum_polyn, ORDER_BY_2); + + while ((num_found_freeq < ORDER) && (j < CHEBYSHEV_NUM_POINTS)) { + j++; + x_high = x_low; + y_high = y_low; + x_low = iusace_chebyshev_polyn_grid[j]; + y_low = iusace_lpc_eval_chebyshev_polyn(x_low, p_sum_polyn, ORDER_BY_2); + + if (y_low * y_high <= 0.0) /* if sign change new root exists */ + { + j--; + for (i = 0; i < CHEBYSHEV_NUM_ITER; i++) { + x_mid = 0.5f * (x_low + x_high); + y_mid = iusace_lpc_eval_chebyshev_polyn(x_mid, p_sum_polyn, ORDER_BY_2); + if (y_low * y_mid <= 0.0) { + y_high = y_mid; + x_high = x_mid; + } else { + y_low = y_mid; + x_low = x_mid; + } + } + + /* linear interpolation for evaluating the root */ + x_lin_interp = x_low - y_low * (x_high - x_low) / (y_high - y_low); + + lsp[num_found_freeq] = x_lin_interp; + num_found_freeq++; + + is_first_polyn = 1 - is_first_polyn; + p_sum_polyn = is_first_polyn ? diff_polyn : sum_polyn; + + x_low = x_lin_interp; + y_low = iusace_lpc_eval_chebyshev_polyn(x_low, p_sum_polyn, ORDER_BY_2); + } + } + + /* Check if ORDER roots found */ + /* if not use the LSPs from previous frame */ + if (num_found_freeq < ORDER) { + for (i = 0; i < ORDER; i++) lsp[i] = prev_lsp[i]; + } +} + +static VOID iusace_compute_coeff_poly_f(FLOAT32 *lsp, FLOAT32 *poly1, FLOAT32 *poly2) { + FLOAT32 b1, b2; + FLOAT32 *ptr_lsp; + WORD32 i, j; + + ptr_lsp = lsp; + poly1[0] = poly2[0] = 1.0f; + + for (i = 1; i <= ORDER_BY_2; i++) { + b1 = -2.0f * (*ptr_lsp++); + b2 = -2.0f * (*ptr_lsp++); + poly1[i] = (b1 * poly1[i - 1]) + (2.0f * poly1[i - 2]); + poly2[i] = (b2 * poly2[i - 1]) + (2.0f * poly2[i - 2]); + for (j = i - 1; j > 0; j--) { + poly1[j] += (b1 * poly1[j - 1]) + poly1[j - 2]; + poly2[j] += (b2 * poly2[j - 1]) + poly2[j - 2]; + } + } +} + +VOID iusace_lsp_to_lp_conversion(FLOAT32 *lsp, FLOAT32 *lp_flt_coff_a) { + WORD32 i; + FLOAT32 *ppoly_f1, *ppoly_f2; + FLOAT32 *plp_flt_coff_a_bott, *plp_flt_coff_a_top; + FLOAT32 poly1[ORDER_BY_2 + 2], poly2[ORDER_BY_2 + 2]; + + poly1[0] = 0.0f; + poly2[0] = 0.0f; + + iusace_compute_coeff_poly_f(lsp, &poly1[1], &poly2[1]); + + ppoly_f1 = poly1 + ORDER_BY_2 + 1; + ppoly_f2 = poly2 + ORDER_BY_2 + 1; + + for (i = 0; i < ORDER_BY_2; i++) { + ppoly_f1[0] += ppoly_f1[-1]; + ppoly_f2[0] -= ppoly_f2[-1]; + ppoly_f1--; + ppoly_f2--; + } + + plp_flt_coff_a_bott = lp_flt_coff_a; + *plp_flt_coff_a_bott++ = 1.0f; + plp_flt_coff_a_top = lp_flt_coff_a + ORDER; + ppoly_f1 = poly1 + 2; + ppoly_f2 = poly2 + 2; + for (i = 0; i < ORDER_BY_2; i++) { + *plp_flt_coff_a_bott++ = 0.5f * (*ppoly_f1 + *ppoly_f2); + *plp_flt_coff_a_top-- = 0.5f * (*ppoly_f1++ - *ppoly_f2++); + } +} + +VOID iusace_levinson_durbin_algo(FLOAT32 *auto_corr_input, FLOAT32 *lpc) { + WORD32 i, j; + FLOAT32 lpc_val, sum, sigma; + FLOAT32 reflection_coeffs[LEV_DUR_MAX_ORDER]; + + lpc[0] = 1.0f; + + reflection_coeffs[0] = -auto_corr_input[1] / auto_corr_input[0]; + lpc[1] = reflection_coeffs[0]; + sigma = auto_corr_input[0] + auto_corr_input[1] * reflection_coeffs[0]; + + for (i = 2; i <= ORDER; i++) { + sum = 0.0f; + for (j = 0; j < i; j++) sum += auto_corr_input[i - j] * lpc[j]; + reflection_coeffs[i - 1] = -sum / sigma; + + sigma = sigma * (1.0f - reflection_coeffs[i - 1] * reflection_coeffs[i - 1]); + + if (sigma <= 1.0E-09f) { + for (j = i; j <= ORDER; j++) { + reflection_coeffs[j - 1] = 0.0f; + lpc[j] = 0.0f; + } + break; + } + + for (j = 1; j <= (i / 2); j++) { + lpc_val = lpc[j] + reflection_coeffs[i - 1] * lpc[i - j]; + lpc[i - j] += reflection_coeffs[i - 1] * lpc[j]; + lpc[j] = lpc_val; + } + + lpc[i] = reflection_coeffs[i - 1]; + } +} + +VOID iusace_get_weighted_lpc(FLOAT32 *lpc, FLOAT32 *weighted_lpc) { + WORD32 i; + for (i = 0; i <= ORDER; i++) { + weighted_lpc[i] = iusace_gamma_table[i] * lpc[i]; + } +} + +VOID iusace_lsp_2_lsf_conversion(FLOAT32 *lsp, FLOAT32 *lsf) { + WORD32 i; + for (i = 0; i < ORDER; i++) { + lsf[i] = (FLOAT32)(acos(lsp[i]) * LSP_2_LSF_SCALE); + } +} + +VOID iusace_lsf_2_lsp_conversion(FLOAT32 *lsf, FLOAT32 *lsp) { + WORD32 i; + for (i = 0; i < ORDER; i++) lsp[i] = (FLOAT32)cos((FLOAT64)lsf[i] * (FLOAT64)PI_BY_6400); +} diff --git a/encoder/iusace_lpc_avq.c b/encoder/iusace_lpc_avq.c new file mode 100644 index 0000000..3ffc99a --- /dev/null +++ b/encoder/iusace_lpc_avq.c @@ -0,0 +1,372 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include "ixheaac_type_def.h" +#include "ixheaace_adjust_threshold_data.h" +#include "iusace_bitbuffer.h" + +/* DRC */ +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" +#include "impd_drc_uni_drc_eq.h" +#include "impd_drc_uni_drc_filter_bank.h" +#include "impd_drc_gain_enc.h" +#include "impd_drc_struct_def.h" + +#include "iusace_cnst.h" +#include "iusace_tns_usac.h" +#include "iusace_psy_mod.h" +#include "iusace_config.h" +#include "iusace_arith_enc.h" +#include "iusace_block_switch_const.h" +#include "iusace_block_switch_struct_def.h" +#include "iusace_fd_qc_util.h" +#include "iusace_fd_quant.h" +#include "iusace_ms.h" +#include "iusace_signal_classifier.h" +#include "ixheaace_sbr_header.h" +#include "ixheaace_config.h" +#include "ixheaace_asc_write.h" +#include "iusace_main.h" +#include "iusace_func_prototypes.h" +#include "iusace_avq_enc.h" + +static VOID iusace_lsf_weight_2st_flt(FLOAT32 *lsfq, FLOAT32 *w, WORD32 mode) { + WORD32 i; + FLOAT32 d[ORDER + 1]; + + d[0] = lsfq[0]; + d[ORDER] = FREQ_MAX - lsfq[ORDER - 1]; + for (i = 1; i < ORDER; i++) { + d[i] = lsfq[i] - lsfq[i - 1]; + } + + for (i = 0; i < ORDER; i++) { + w[i] = (FLOAT32)(iusace_wlsf_factor_table[mode] / (FREQ_DIV / sqrt(d[i] * d[i + 1]))); + } +} + +static VOID iusace_lsf_weight(FLOAT32 *lsf, FLOAT32 *ptr_w) { + WORD32 i; + FLOAT32 d[ORDER + 1]; + + d[0] = lsf[0]; + d[ORDER] = FREQ_MAX - lsf[ORDER - 1]; + for (i = 1; i < ORDER; i++) { + d[i] = lsf[i] - lsf[i - 1]; + } + + for (i = 0; i < ORDER; i++) { + ptr_w[i] = (1.0f / d[i]) + (1.0f / d[i + 1]); + } + + return; +} + +static WORD32 iusace_avq_first_approx_abs(FLOAT32 *lsf, FLOAT32 *lsfq) { + WORD32 i, j, index; + FLOAT32 w[ORDER]; + FLOAT32 dist_min, dist, temp; + const FLOAT32 *p_dico; + + iusace_lsf_weight(lsf, w); + + dist_min = 1.0e30f; + p_dico = iusace_dico_lsf_abs_8b_flt; + index = 0; + + for (i = 0; i < 256; i++) { + dist = 0.0; + for (j = 0; j < ORDER; j++) { + temp = lsf[j] - *p_dico++; + dist += w[j] * temp * temp; + } + if (dist < dist_min) { + dist_min = dist; + index = i; + } + } + + for (j = 0; j < ORDER; j++) { + lsfq[j] = iusace_dico_lsf_abs_8b_flt[index * ORDER + j]; + } + + return index; +} + +static WORD32 iusace_avq_first_approx_rel(FLOAT32 *ptr_lsf, FLOAT32 *ptr_lsfq, WORD32 *idx, + WORD32 mode) { + WORD32 i, num_bits; + FLOAT32 w[ORDER], x[ORDER], temp; + WORD32 nq, avq[ORDER]; + FLOAT32 lsf_min; + + iusace_lsf_weight_2st_flt(ptr_lsf, w, 1); + + temp = 0.0f; + for (i = 0; i < ORDER; i++) { + x[i] = (ptr_lsf[i] - ptr_lsfq[i]) / w[i]; + temp += x[i] * x[i]; + } + + if (temp < 8.0f) { + idx[0] = 0; + idx[1] = 0; + if ((mode == 0) || (mode == 3)) { + return (10); + } else if (mode == 1) { + return (2); + } else { + return (6); + } + } + + iusace_lsf_weight_2st_flt(ptr_lsfq, w, mode); + + for (i = 0; i < ORDER; i++) { + x[i] = (ptr_lsf[i] - ptr_lsfq[i]) / w[i]; + } + + iusace_alg_vec_quant(x, avq, idx); + + for (i = 0; i < ORDER; i++) { + ptr_lsfq[i] += (w[i] * (FLOAT32)avq[i]); + } + + num_bits = 0; + for (i = 0; i < 2; i++) { + nq = idx[i]; + + if ((mode == 0) || (mode == 3)) { + num_bits += (2 + (nq * 4)); + if (nq > 6) { + num_bits += nq - 3; + } else if (nq > 4) { + num_bits += nq - 4; + } else if (nq == 0) { + num_bits += 3; + } + } else if (mode == 1) { + num_bits += nq * 5; + if (nq == 0) { + num_bits += 1; + } + } else { + num_bits += (2 + (nq * 4)); + if (nq == 0) { + num_bits += 1; + } else if (nq > 4) { + num_bits += nq - 3; + } + } + } + + lsf_min = LSF_GAP; + for (i = 0; i < ORDER; i++) { + if (ptr_lsfq[i] < lsf_min) { + ptr_lsfq[i] = lsf_min; + } + + lsf_min = ptr_lsfq[i] + LSF_GAP; + } + + lsf_min = FREQ_MAX - LSF_GAP; + for (i = ORDER - 1; i >= 0; i--) { + if (ptr_lsfq[i] > lsf_min) { + ptr_lsfq[i] = lsf_min; + } + + lsf_min = ptr_lsfq[i] - LSF_GAP; + } + + return (num_bits); +} + +VOID iusace_quantize_lpc_avq(FLOAT32 *ptr_lsf, FLOAT32 *ptr_lsfq, WORD32 lpc0, + WORD32 *ptr_lpc_idx, WORD32 *nb_indices, WORD32 *nbbits) { + WORD32 i; + FLOAT32 lsfq[ORDER]; + WORD32 *ptr_index, indxt[100], num_bits, nbt, nit; + + ptr_index = &ptr_lpc_idx[0]; + *nb_indices = 0; + *nbbits = 0; + + ptr_index[0] = iusace_avq_first_approx_abs(&ptr_lsf[3 * ORDER], &ptr_lsfq[3 * ORDER]); + + nbt = iusace_avq_first_approx_rel(&ptr_lsf[3 * ORDER], &ptr_lsfq[3 * ORDER], &ptr_index[1], 0); + nit = 1 + iusace_get_num_params(&ptr_lpc_idx[1]); + + ptr_index += nit; + *nb_indices += nit; + *nbbits += 8 + nbt; + + if (lpc0) { + *ptr_index = 0; + ptr_index++; + *nb_indices += 1; + *nbbits += 1; + + ptr_index[0] = iusace_avq_first_approx_abs(&ptr_lsf[-ORDER], &ptr_lsfq[-ORDER]); + + num_bits = iusace_avq_first_approx_rel(&ptr_lsf[-ORDER], &ptr_lsfq[-ORDER], &ptr_index[1], 0); + nbt = 8 + num_bits; + nit = 1 + iusace_get_num_params(&ptr_index[1]); + + for (i = 0; i < ORDER; i++) lsfq[i] = ptr_lsfq[3 * ORDER + i]; + + num_bits = iusace_avq_first_approx_rel(&ptr_lsf[-ORDER], &lsfq[0], indxt, 3); + + if (num_bits < nbt) { + nbt = num_bits; + nit = iusace_get_num_params(&indxt[0]); + ptr_index[-1] = 1; + for (i = 0; i < ORDER; i++) ptr_lsfq[-ORDER + i] = lsfq[i]; + for (i = 0; i < nit; i++) ptr_index[i] = indxt[i]; + } + + ptr_index += nit; + *nb_indices += nit; + *nbbits += nbt; + } + + *ptr_index = 0; + ptr_index++; + *nb_indices += 1; + *nbbits += 1; + + ptr_index[0] = iusace_avq_first_approx_abs(&ptr_lsf[ORDER], &ptr_lsfq[ORDER]); + + num_bits = iusace_avq_first_approx_rel(&ptr_lsf[ORDER], &ptr_lsfq[ORDER], &ptr_index[1], 0); + nbt = 8 + num_bits; + nit = 1 + iusace_get_num_params(&ptr_index[1]); + + for (i = 0; i < ORDER; i++) lsfq[i] = ptr_lsfq[3 * ORDER + i]; + + num_bits = iusace_avq_first_approx_rel(&ptr_lsf[ORDER], &lsfq[0], indxt, 3); + + if (num_bits < nbt) { + nbt = num_bits; + nit = iusace_get_num_params(&indxt[0]); + ptr_index[-1] = 1; + for (i = 0; i < ORDER; i++) ptr_lsfq[ORDER + i] = lsfq[i]; + for (i = 0; i < nit; i++) ptr_index[i] = indxt[i]; + } + + ptr_index += nit; + *nb_indices += nit; + *nbbits += nbt; + + *ptr_index = 0; + ptr_index++; + *nb_indices += 1; + + ptr_index[0] = iusace_avq_first_approx_abs(&ptr_lsf[0], &ptr_lsfq[0]); + + num_bits = iusace_avq_first_approx_rel(&ptr_lsf[0], &ptr_lsfq[0], &ptr_index[1], 0); + nbt = 2 + 8 + num_bits; + nit = 1 + iusace_get_num_params(&ptr_index[1]); + + for (i = 0; i < ORDER; i++) lsfq[i] = 0.5f * (ptr_lsfq[-ORDER + i] + ptr_lsfq[ORDER + i]); + + num_bits = iusace_avq_first_approx_rel(&ptr_lsf[0], lsfq, indxt, 1); + + if (num_bits < 10) { + nbt = 2; + nit = 0; + ptr_index[-1] = 1; + for (i = 0; i < ORDER; i++) ptr_lsfq[i] = lsfq[i]; + } + + for (i = 0; i < ORDER; i++) lsfq[i] = ptr_lsfq[ORDER + i]; + + num_bits = iusace_avq_first_approx_rel(&ptr_lsf[0], lsfq, indxt, 2); + num_bits += 1; + + if (num_bits < nbt) { + nbt = num_bits; + nit = iusace_get_num_params(&indxt[0]); + ptr_index[-1] = 2; + for (i = 0; i < ORDER; i++) ptr_lsfq[i] = lsfq[i]; + for (i = 0; i < nit; i++) ptr_index[i] = indxt[i]; + } + + ptr_index += nit; + *nb_indices += nit; + *nbbits += nbt; + + *ptr_index = 0; + ptr_index++; + *nb_indices += 1; + + ptr_index[0] = iusace_avq_first_approx_abs(&ptr_lsf[2 * ORDER], &ptr_lsfq[2 * ORDER]); + + num_bits = + iusace_avq_first_approx_rel(&ptr_lsf[2 * ORDER], &ptr_lsfq[2 * ORDER], &ptr_index[1], 0); + nbt = 2 + 8 + num_bits; + nit = 1 + iusace_get_num_params(&ptr_index[1]); + + for (i = 0; i < ORDER; i++) lsfq[i] = 0.5f * (ptr_lsfq[ORDER + i] + ptr_lsfq[3 * ORDER + i]); + + num_bits = iusace_avq_first_approx_rel(&ptr_lsf[2 * ORDER], lsfq, indxt, 1); + num_bits += 1; + + if (num_bits < nbt) { + nbt = num_bits; + nit = iusace_get_num_params(&indxt[0]); + ptr_index[-1] = 1; + for (i = 0; i < ORDER; i++) ptr_lsfq[2 * ORDER + i] = lsfq[i]; + for (i = 0; i < nit; i++) ptr_index[i] = indxt[i]; + } + + for (i = 0; i < ORDER; i++) lsfq[i] = ptr_lsfq[ORDER + i]; + + num_bits = iusace_avq_first_approx_rel(&ptr_lsf[2 * ORDER], lsfq, indxt, 2); + num_bits += 3; + + if (num_bits < nbt) { + nbt = num_bits; + nit = iusace_get_num_params(&indxt[0]); + ptr_index[-1] = 2; + for (i = 0; i < ORDER; i++) ptr_lsfq[2 * ORDER + i] = lsfq[i]; + for (i = 0; i < nit; i++) ptr_index[i] = indxt[i]; + } + + for (i = 0; i < ORDER; i++) lsfq[i] = ptr_lsfq[3 * ORDER + i]; + + num_bits = iusace_avq_first_approx_rel(&ptr_lsf[2 * ORDER], lsfq, indxt, 2); + num_bits += 3; + + if (num_bits < nbt) { + nbt = num_bits; + nit = iusace_get_num_params(&indxt[0]); + ptr_index[-1] = 3; + for (i = 0; i < ORDER; i++) ptr_lsfq[2 * ORDER + i] = lsfq[i]; + for (i = 0; i < nit; i++) ptr_index[i] = indxt[i]; + } + + *nb_indices += nit; + *nbbits += nbt; + + return; +} diff --git a/encoder/iusace_lpd.h b/encoder/iusace_lpd.h new file mode 100644 index 0000000..86a4948 --- /dev/null +++ b/encoder/iusace_lpd.h @@ -0,0 +1,67 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +VOID iusace_autocorr_plus(FLOAT32 *speech, FLOAT32 *auto_corr_vector, WORD32 window_len, + const FLOAT32 *lp_analysis_win, FLOAT32 *temp_aut_corr); +VOID iusace_compute_lp_residual(FLOAT32 *a, FLOAT32 *x, FLOAT32 *y, WORD32 l); +VOID iusace_convolve(FLOAT32 *signal, FLOAT32 *wsynth_filter_ir, FLOAT32 *conv_out); +VOID iusace_synthesis_tool_float(FLOAT32 *a, FLOAT32 *x, FLOAT32 *y, WORD32 l, FLOAT32 *mem, + FLOAT32 *buf_synth_tool); +VOID iusace_apply_preemph(FLOAT32 *signal, FLOAT32 factor, WORD32 length, FLOAT32 *mem); +VOID iusace_apply_deemph(FLOAT32 *signal, FLOAT32 factor, WORD32 length, FLOAT32 *mem); +VOID iusace_lpc_2_lsp_conversion(FLOAT32 *lpc, FLOAT32 *lsp, FLOAT32 *prev_lsp); +VOID iusace_levinson_durbin_algo(FLOAT32 *auto_corr_input, FLOAT32 *lpc); +VOID iusace_get_weighted_lpc(FLOAT32 *lpc, FLOAT32 *weighted_lpc); +VOID iusace_lsp_2_lsf_conversion(FLOAT32 *lsp, FLOAT32 *lsf); +VOID iusace_lsf_2_lsp_conversion(FLOAT32 *lsf, FLOAT32 *lsp); +VOID iusace_open_loop_search(FLOAT32 *wsp, WORD32 min_pitch_lag, WORD32 max_pitch_lag, + WORD32 num_frame, WORD32 *ol_pitch_lag, + ia_usac_td_encoder_struct *st); +WORD32 iusace_get_ol_lag_median(WORD32 prev_ol_lag, WORD32 *prev_ol_lags); +VOID iusace_closed_loop_search(FLOAT32 *exc, FLOAT32 *xn, FLOAT32 *wsyn_filt_ir, + WORD32 search_range_min, WORD32 search_range_max, WORD32 *pit_frac, + WORD32 is_first_subfrm, WORD32 min_pitch_lag_res1_2, + WORD32 min_pitch_lag_res_1, WORD32 *pitch_lag_out); +VOID iusace_decim2_fir_filter(FLOAT32 *signal, WORD32 length, FLOAT32 *mem, + FLOAT32 *scratch_fir_sig_buf); +FLOAT32 iusace_calc_sq_gain(FLOAT32 *x, WORD32 num_bits, WORD32 length, + FLOAT32 *scratch_sq_gain_en); +VOID iusace_lpc_coef_gen(FLOAT32 *lsf_old, FLOAT32 *lsf_new, FLOAT32 *a, WORD32 nb_subfr, + WORD32 m); +VOID iusace_interpolation_lsp_params(FLOAT32 *lsp_old, FLOAT32 *lsp_new, FLOAT32 *lp_flt_coff_a, + WORD32 nb_subfr); + +VOID iusace_acelp_tgt_ir_corr(FLOAT32 *x, FLOAT32 *ir_wsyn, FLOAT32 *corr_out); + +VOID iusace_acelp_tgt_cb_corr1(FLOAT32 *xn, FLOAT32 *y1, FLOAT32 *y2, FLOAT32 *corr_out); + +FLOAT32 iusace_acelp_tgt_cb_corr2(FLOAT32 *xn, FLOAT32 *y1, FLOAT32 *corr_out); + +VOID iusace_acelp_cb_target_update(FLOAT32 *x, FLOAT32 *x2, FLOAT32 *y, FLOAT32 gain); + +VOID iusace_acelp_cb_exc(FLOAT32 *corr_input, FLOAT32 *lp_residual, FLOAT32 *ir_wsyn, + WORD16 *alg_cb_exc_out, FLOAT32 *filt_cb_exc, WORD32 num_bits_cb, + WORD32 *acelp_param_out, FLOAT32 *scratch_acelp_ir_buf); + +VOID iusace_acelp_ltpred_cb_exc(FLOAT32 *exc, WORD32 t0, WORD32 t0_frac, WORD32 len_subfrm); + +VOID iusace_acelp_quant_gain(FLOAT32 *code, FLOAT32 *pitch_gain, FLOAT32 *code_gain, + FLOAT32 *tgt_cb_corr_data, FLOAT32 mean_energy, WORD32 *qunt_idx); diff --git a/encoder/iusace_lpd_enc.c b/encoder/iusace_lpd_enc.c new file mode 100644 index 0000000..2f91c9d --- /dev/null +++ b/encoder/iusace_lpd_enc.c @@ -0,0 +1,818 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include +#include "ixheaac_type_def.h" +#include "ixheaace_adjust_threshold_data.h" +#include "iusace_bitbuffer.h" + +/* DRC */ +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" +#include "impd_drc_uni_drc_eq.h" +#include "impd_drc_uni_drc_filter_bank.h" +#include "impd_drc_gain_enc.h" +#include "impd_drc_struct_def.h" + +#include "iusace_cnst.h" +#include "iusace_tns_usac.h" +#include "iusace_psy_mod.h" +#include "iusace_psy_utils.h" +#include "iusace_tns_usac.h" +#include "iusace_config.h" +#include "iusace_arith_enc.h" +#include "iusace_fd_qc_util.h" +#include "iusace_fd_quant.h" +#include "iusace_block_switch_const.h" +#include "iusace_block_switch_struct_def.h" +#include "iusace_ms.h" +#include "iusace_signal_classifier.h" +#include "ixheaace_sbr_header.h" +#include "ixheaace_config.h" +#include "ixheaace_asc_write.h" +#include "iusace_main.h" +#include "iusace_lpd_rom.h" +#include "iusace_lpd.h" +#include "iusace_func_prototypes.h" + +VOID iusace_init_td_data(ia_usac_td_encoder_struct *st, WORD32 len_frame) { + WORD32 len_window; + WORD32 num_frames = NUM_FRAMES; + st->len_subfrm = len_frame / num_frames; + + st->len_frame = len_frame; + st->num_subfrm = (MAX_NUM_SUBFR * len_frame) / LEN_SUPERFRAME; + + iusace_reset_td_enc(st); + st->prev_mode = -1; + st->arith_reset_flag = 1; + + if (st->fscale <= FSCALE_DENOM) { + len_window = (LEN_LP_WINDOW * len_frame) / LEN_SUPERFRAME; + } else { + len_window = (LEN_LP_WINDOW_HIGH_RATE * len_frame) / LEN_SUPERFRAME; + } + + switch (len_window) { + case 512: + st->lp_analysis_window = iusace_cos_window_512; + break; + case 448: + st->lp_analysis_window = iusace_cos_window_448; + break; + case 384: + st->lp_analysis_window = iexheaac_cos_window_384; + break; + default: + st->lp_analysis_window = iusace_cos_window_512; + break; + } + return; +} + +VOID iusace_config_acelp_core_mode(ia_usac_td_encoder_struct *st, WORD32 sampling_rate, + WORD32 bitrate) { + WORD32 max_bits, coder_bits; + const WORD32 *p_acelp_core_numbits_table; + + p_acelp_core_numbits_table = (WORD32 *)iusace_acelp_core_numbits_1024; + + max_bits = (WORD32)((FLOAT32)(bitrate * LEN_SUPERFRAME) / (FLOAT32)sampling_rate); + + for (st->acelp_core_mode = 5; st->acelp_core_mode >= 0; st->acelp_core_mode--) { + coder_bits = p_acelp_core_numbits_table[st->acelp_core_mode]; + if (coder_bits <= max_bits) { + return; + } + } + if (st->acelp_core_mode == -1) { + st->acelp_core_mode = 0; + } + return; +} + +VOID iusace_reset_td_enc(ia_usac_td_encoder_struct *st) { + WORD32 i; + + memset(st->old_speech_pe, 0, (ORDER + LEN_NEXT_HIGH_RATE) * sizeof(FLOAT32)); + memset(st->prev_exc, 0, (MAX_PITCH + LEN_INTERPOL) * sizeof(FLOAT32)); + memset(st->prev_wsp, 0, (MAX_PITCH / OPL_DECIM) * sizeof(FLOAT32)); + memset(st->mem_lp_decim2, 0, 3 * sizeof(FLOAT32)); + memset(st->weighted_sig, 0, 128 * sizeof(FLOAT32)); + + st->lpd_state.mode = -1; + st->lpd_state.num_bits = 0; + memset(st->lpd_state.lpc_coeffs_quant, 0, (2 * (ORDER + 1)) * sizeof(FLOAT32)); + memset(st->lpd_state.lpc_coeffs, 0, (2 * (ORDER + 1)) * sizeof(FLOAT32)); + memset(st->lpd_state.synth, 0, (ORDER + 128) * sizeof(FLOAT32)); + memset(st->lpd_state.wsynth, 0, (1 + 128) * sizeof(FLOAT32)); + + memset(st->lpd_state.acelp_exc, 0, (2 * LEN_FRAME) * sizeof(FLOAT32)); + + memset(st->lpd_state.tcx_mem, 0, 128 * sizeof(FLOAT32)); + memset(st->lpd_state.tcx_quant, 0, (1 + 256) * sizeof(FLOAT32)); + st->lpd_state.tcx_fac = 0.0f; + + memset(st->prev_hp_wsp, 0, + (LEN_SUPERFRAME / OPL_DECIM + (MAX_PITCH / OPL_DECIM)) * sizeof(FLOAT32)); + + memset(st->hp_ol_ltp_mem, 0, (3 * 2 + 1) * sizeof(FLOAT32)); + for (i = 0; i < 5; i++) st->prev_ol_lags[i] = 40; + st->prev_wsyn_mem = 0.0; + st->prev_wsp_mem = 0.0; + st->prev_xnq_mem = 0.0; + st->mem_wsp = 0.0; + st->prev_ovlp_size = 0; + st->prev_pitch_med = 40; + st->ol_wght_flg = 0; + st->ada_w = 0.0; + + memcpy(st->isf_old, iusace_lsf_init, ORDER * sizeof(FLOAT32)); + memcpy(st->isp_old, iusace_ispold_init, ORDER * sizeof(FLOAT32)); + memcpy(st->isp_old_q, st->isp_old, ORDER * sizeof(FLOAT32)); + + st->mem_preemph = 0.0; + memset(st->mem_sig_in, 0, 4 * sizeof(FLOAT32)); + memset(st->xn_buffer, 0, 128 * sizeof(FLOAT32)); + + return; +} + +VOID iusace_highpass_prev_wsp(ia_usac_td_encoder_struct *st, FLOAT32 *decim_sig, + WORD32 pitch_max) { + WORD32 i, k; + WORD32 wsp_offset = pitch_max / OPL_DECIM; + WORD32 num_frames = (2 * LEN_SUBFR) / OPL_DECIM; + FLOAT32 *hp_wsp_mem = st->hp_ol_ltp_mem; + FLOAT32 *prev_hp_wsp = st->prev_hp_wsp; + for (i = 0; i < 2 * st->len_subfrm / OPL_DECIM; i += num_frames) { + FLOAT32 *data_a, *data_b, *hp_wsp, o; + FLOAT32 *wsp = decim_sig + ORDER + i; + data_a = hp_wsp_mem; + data_b = hp_wsp_mem + HP_ORDER; + hp_wsp = prev_hp_wsp + wsp_offset; + for (k = 0; k < num_frames; k++) { + data_b[0] = data_b[1]; + data_b[1] = data_b[2]; + data_b[2] = data_b[3]; + data_b[HP_ORDER] = wsp[k]; + o = data_b[0] * 0.83787057505665F; + o += data_b[1] * -2.50975570071058F; + o += data_b[2] * 2.50975570071058F; + o += data_b[3] * -0.83787057505665F; + o -= data_a[0] * -2.64436711600664F; + o -= data_a[1] * 2.35087386625360F; + o -= data_a[2] * -0.70001156927424F; + data_a[2] = data_a[1]; + data_a[1] = data_a[0]; + data_a[0] = o; + hp_wsp[k] = o; + } + memmove(prev_hp_wsp, &prev_hp_wsp[num_frames], wsp_offset * sizeof(FLOAT32)); + } +} + +VOID iusace_find_weighted_speech(FLOAT32 *filter_coef, FLOAT32 *speech, FLOAT32 *wsp, + FLOAT32 *mem_wsp, WORD32 length) { + WORD32 i_subfr; + FLOAT32 weighted_lpc[ORDER + 1]; + for (i_subfr = 0; i_subfr < length; i_subfr += LEN_SUBFR) { + iusace_get_weighted_lpc(filter_coef, weighted_lpc); + iusace_compute_lp_residual(weighted_lpc, &speech[i_subfr], &wsp[i_subfr], LEN_SUBFR); + filter_coef += (ORDER + 1); + } + iusace_apply_deemph(wsp, TILT_FAC, length, mem_wsp); + return; +} + +VOID iusace_get_interpolated_lpc(FLOAT32 *lsp_old, FLOAT32 *lsp_new, FLOAT32 *lpc, + WORD32 num_subfrm) { + FLOAT32 lsp[ORDER], *p_lpc, inc, fnew, fold; + WORD32 i, k; + + inc = 1.0f / (FLOAT32)num_subfrm; + p_lpc = lpc; + fnew = 0.0f; + + for (k = 0; k < num_subfrm; k++) { + fold = 1.0f - fnew; + for (i = 0; i < ORDER; i++) { + lsp[i] = (FLOAT32)(lsp_old[i] * fold + lsp_new[i] * fnew); + } + fnew += inc; + iusace_lsp_to_lp_conversion(lsp, p_lpc); + p_lpc += (ORDER + 1); + } + + iusace_lsp_to_lp_conversion(lsp_new, p_lpc); +} + +VOID iusace_core_lpd_encode(ia_usac_data_struct *usac_data, FLOAT32 *speech, WORD32 *mode, + WORD32 *num_tcx_param, WORD32 ch_idx) { + WORD32 first_lpd_flag = (usac_data->core_mode_prev[ch_idx] == CORE_MODE_FD); + iusace_scratch_mem *pstr_scratch = &usac_data->str_scratch; + WORD32 pit_adj = usac_data->td_encoder[ch_idx]->fscale; + WORD32 *num_fac_bits = &usac_data->num_td_fac_bits[ch_idx]; + WORD16 *serial_fac_out = usac_data->fac_out_stream[ch_idx]; + WORD32 *lpc_params = usac_data->param_buf + (NUM_FRAMES * MAX_NUM_TCX_PRM_PER_DIV); + ia_usac_td_encoder_struct *st = usac_data->td_encoder[ch_idx]; + WORD32 *acelp_tcx_params = usac_data->param_buf; + WORD16 *codec_mode = &st->acelp_core_mode; + const FLOAT32 *lp_analysis_window = st->lp_analysis_window; + FLOAT32 *lp_filter_coeff = pstr_scratch->p_lp_filter_coeff; + FLOAT32 *lp_filter_coeff_q = pstr_scratch->p_lp_filter_coeff_q; + + FLOAT32 *ptr_stack_mem = (FLOAT32 *)pstr_scratch->ptr_stack_mem; + + FLOAT32 *auto_corr_vector = ptr_stack_mem; + ptr_stack_mem += (ORDER + 1); + memset(auto_corr_vector, 0, sizeof(*auto_corr_vector) * (ORDER + 1)); + + FLOAT32 *isp_new = ptr_stack_mem; + ptr_stack_mem += ORDER; + memset(isp_new, 0, sizeof(*isp_new) * (ORDER)); + + FLOAT32 *isp_curr = ptr_stack_mem; + ptr_stack_mem += ((NUM_FRAMES + 1) * ORDER); + memset(isp_curr, 0, sizeof(*isp_curr) * ((NUM_FRAMES + 1) * ORDER)); + + FLOAT32 *isp_curr_q = ptr_stack_mem; + ptr_stack_mem += ((NUM_FRAMES + 1) * ORDER); + memset(isp_curr_q, 0, sizeof(*isp_curr_q) * ((NUM_FRAMES + 1) * ORDER)); + + FLOAT32 *isf_curr = ptr_stack_mem; + ptr_stack_mem += ((NUM_FRAMES + 1) * ORDER); + memset(isf_curr, 0, sizeof(*isf_curr) * ((NUM_FRAMES + 1) * ORDER)); + + FLOAT32 *isf_curr_q = ptr_stack_mem; + ptr_stack_mem += ((NUM_FRAMES + 1) * ORDER); + memset(isf_curr_q, 0, sizeof(*isf_curr_q) * ((NUM_FRAMES + 1) * ORDER)); + + FLOAT32 *auto_corr_lp_filter_coeff = ptr_stack_mem; + ptr_stack_mem += (ORDER + 1); + memset(auto_corr_lp_filter_coeff, 0, sizeof(*auto_corr_lp_filter_coeff) * (ORDER + 1)); + + WORD32 num_indices = 0, num_bits = 0; + WORD32 *prm_tcx = pstr_scratch->p_prm_tcx; + FLOAT32 *p_wsp_prev_buf; + FLOAT32 *wsp_prev_buf = pstr_scratch->p_wsp_prev_buf; + memset(lp_filter_coeff, 0, ((NUM_SUBFR_SUPERFRAME + 1) * (ORDER + 1)) * sizeof(FLOAT32)); + memset(lp_filter_coeff_q, 0, ((NUM_SUBFR_SUPERFRAME + 1) * (ORDER + 1)) * sizeof(FLOAT32)); + memset(wsp_prev_buf, 0, ((MAX_PITCH1 / OPL_DECIM) + LEN_FRAME) * sizeof(FLOAT32)); + WORD32 i, j, k, i1, i2; + WORD32 *p_params; + FLOAT32 energy = 0, max_corr = 0, t0 = 0, *p, *p1; + WORD32 ol_pitch_lag[2 * NUM_FRAMES] = {0}; + FLOAT32 norm_corr[2 * NUM_FRAMES] = {0}; + WORD32 num_params, pitch_min, pitch_max; + + ia_usac_lpd_state_struct *lpd_state[6], *lpd_state_temp; + lpd_state_temp = (ia_usac_lpd_state_struct *)ptr_stack_mem; + ptr_stack_mem += + (sizeof(ia_usac_lpd_state_struct) + sizeof(*ptr_stack_mem)) / (sizeof(*ptr_stack_mem)); + memset(lpd_state_temp, 0, sizeof(*lpd_state_temp)); + for (j = 0; j < 6; j++) { + lpd_state[j] = (ia_usac_lpd_state_struct *)ptr_stack_mem; + ptr_stack_mem += + (sizeof(ia_usac_lpd_state_struct) + sizeof(*ptr_stack_mem)) / (sizeof(*ptr_stack_mem)); + memset(lpd_state[j], 0, sizeof(*lpd_state[0])); + } + + WORD32 num_bits_acelp = 0, num_bits_tcx = 0; + WORD32 range_pitch_search = 0; + WORD32 len_subfrm = 0; + WORD32 num_subfrm = 0; + WORD32 num_sbfrm_per_supfrm = 0; + WORD32 window_len = 0; + WORD32 len = (MAX_PITCH / OPL_DECIM); + FLOAT32 mem_wsyn; + FLOAT32 ssnr_256 = 0.0f, ssnr_512 = 0.0f, ssnr_1024 = 0.0f; + FLOAT32 tmp_ssnr = 0.0f; + + len_subfrm = st->len_subfrm; + num_subfrm = st->num_subfrm; + num_sbfrm_per_supfrm = NUM_FRAMES * num_subfrm; + + if (pit_adj <= FSCALE_DENOM) { + window_len = (LEN_LP_WINDOW * len_subfrm) / LEN_FRAME; + } else { + window_len = (LEN_LP_WINDOW_HIGH_RATE * len_subfrm) / LEN_FRAME; + } + + memcpy(pstr_scratch->p_wsig_buf, st->weighted_sig, 128 * sizeof(FLOAT32)); + + num_bits_acelp = (iusace_acelp_core_numbits_1024[*codec_mode] - NBITS_MODE) >> 2; + + num_bits_tcx = (WORD32)(0.85f * num_bits_acelp - NBITS_LPC); + + if (pit_adj == 0) { + pitch_min = TMIN; + pitch_max = TMAX; + } else { + i = (((pit_adj * TMIN) + (FSCALE_DENOM / 2)) / FSCALE_DENOM) - TMIN; + pitch_min = TMIN + i; + pitch_max = TMAX + (6 * i); + } + + p_wsp_prev_buf = wsp_prev_buf + MAX_PITCH1 / OPL_DECIM; + memcpy(wsp_prev_buf, st->prev_wsp, (WORD32)((MAX_PITCH / OPL_DECIM) * sizeof(FLOAT32))); + + if (first_lpd_flag) { + memcpy(st->isp_old, iusace_ispold_init, ORDER * sizeof(FLOAT32)); + + iusace_autocorr_plus(&speech[-(window_len / 2)], auto_corr_vector, window_len, + (FLOAT32 *)lp_analysis_window, pstr_scratch->p_buf_aut_corr); + + for (j = 0; j <= ORDER; j++) { + auto_corr_vector[j] *= (FLOAT32)iusace_lag_window[j]; + } + + iusace_levinson_durbin_algo(auto_corr_vector, auto_corr_lp_filter_coeff); + iusace_lpc_2_lsp_conversion(auto_corr_lp_filter_coeff, isp_new, st->isp_old); + memcpy(st->isp_old, isp_new, ORDER * sizeof(FLOAT32)); + iusace_lsp_2_lsf_conversion(isp_new, isf_curr); + memcpy(st->isf_old, isf_curr, ORDER * sizeof(FLOAT32)); + } + + memcpy(isp_curr, st->isp_old, ORDER * sizeof(FLOAT32)); + + for (i = 0; i < NUM_FRAMES; i++) { + iusace_autocorr_plus(&speech[((i + 1) * len_subfrm) - (window_len / 2)], auto_corr_vector, + window_len, (FLOAT32 *)lp_analysis_window, pstr_scratch->p_buf_aut_corr); + + for (j = 0; j <= ORDER; j++) { + auto_corr_vector[j] *= (FLOAT32)iusace_lag_window[j]; + } + + iusace_levinson_durbin_algo(auto_corr_vector, auto_corr_lp_filter_coeff); + iusace_lpc_2_lsp_conversion(auto_corr_lp_filter_coeff, isp_new, st->isp_old); + memcpy(&isp_curr[(i + 1) * ORDER], isp_new, ORDER * sizeof(FLOAT32)); + iusace_interpolation_lsp_params(st->isp_old, isp_new, + &lp_filter_coeff[i * num_subfrm * (ORDER + 1)], num_subfrm); + iusace_lsp_2_lsf_conversion(&isp_curr[(i + 1) * ORDER], &isf_curr[(i + 1) * ORDER]); + memcpy(st->isp_old, isp_new, ORDER * sizeof(FLOAT32)); + } + + memcpy(isf_curr, st->isf_old, ORDER * sizeof(FLOAT32)); + memcpy(st->isf_old, &isf_curr[NUM_FRAMES * ORDER], ORDER * sizeof(FLOAT32)); + + if (!first_lpd_flag) { + iusace_lsp_2_lsf_conversion(st->isp_old_q, isf_curr_q); + } + + iusace_quantize_lpc_avq(&isf_curr[ORDER], &isf_curr_q[ORDER], first_lpd_flag, &lpc_params[0], + &num_indices, &num_bits); + + for (i = 0; i < NUM_FRAMES; i++) { + iusace_lsf_2_lsp_conversion(&isf_curr_q[(i + 1) * ORDER], &isp_curr_q[(i + 1) * ORDER]); + } + + if (first_lpd_flag) { + iusace_lsf_2_lsp_conversion(isf_curr_q, isp_curr_q); + memcpy(st->isp_old_q, isp_curr_q, ORDER * sizeof(FLOAT32)); + } + + *num_fac_bits = 0; + if (first_lpd_flag) { + FLOAT32 *temp_speech = pstr_scratch->p_buf_speech; + FLOAT32 *temp_res = pstr_scratch->p_buf_res; + FLOAT32 lpc[9 * (ORDER + 1)]; + FLOAT32 hp_mem[4]; + FLOAT32 premph_mem = 0.0f; + WORD32 fac_length; + WORD32 num_bits_fac = (WORD32)((FLOAT32)num_bits_tcx / 2.f); + FLOAT32 *temp_signal = pstr_scratch->p_buf_signal; + + if (st->last_was_short) { + fac_length = (st->len_frame) / 16; + } else { + fac_length = len_subfrm / 2; + } + + iusace_get_interpolated_lpc(st->isp_old_q, st->isp_old_q, lpc, (2 * len_subfrm) / LEN_SUBFR); + + memset(temp_speech, 0, (ORDER + 2 * len_subfrm) * sizeof(FLOAT32)); + memset(temp_res, 0, (2 * len_subfrm) * sizeof(FLOAT32)); + + iusace_fac_apply(&st->fd_orig[1 + ORDER], len_subfrm, fac_length, st->low_pass_line, + num_bits_fac, &st->fd_synth[1 + ORDER], lpc, serial_fac_out, num_fac_bits, + pstr_scratch); + memset(hp_mem, 0, 4 * sizeof(FLOAT32)); + iusace_highpass_50hz_12k8(st->fd_orig, 2 * len_subfrm + 1 + ORDER, hp_mem, pit_adj); + premph_mem = 0.0f; + iusace_apply_preemph(st->fd_orig, PREEMPH_FILT_FAC, 2 * len_subfrm + 1 + ORDER, &premph_mem); + + memcpy(temp_signal, st->fd_orig + len_subfrm + 1, (len_subfrm + ORDER) * sizeof(FLOAT32)); + premph_mem = temp_signal[0]; + iusace_apply_deemph(temp_signal, PREEMPH_FILT_FAC, len_subfrm + ORDER, &premph_mem); + memcpy(st->lpd_state.tcx_mem, &temp_signal[len_subfrm + ORDER - 128], 128 * sizeof(FLOAT32)); + + premph_mem = 0.0f; + iusace_apply_preemph(st->fd_synth, PREEMPH_FILT_FAC, 2 * len_subfrm + 1 + ORDER, &premph_mem); + memcpy(st->lpd_state.synth, st->fd_synth + 2 * len_subfrm - ORDER - 128 + 1 + ORDER, + (ORDER + 128) * sizeof(FLOAT32)); + memcpy(temp_speech + ORDER, st->fd_synth + 1 + ORDER, 2 * len_subfrm * sizeof(FLOAT32)); + + premph_mem = 0.0f; + iusace_find_weighted_speech(lpc, temp_speech + ORDER, temp_res, &premph_mem, 2 * len_subfrm); + st->prev_wsyn_mem = premph_mem; + memcpy(st->lpd_state.wsynth, temp_res + 2 * len_subfrm - ORDER - 128, + (ORDER + 128) * sizeof(FLOAT32)); + memcpy(temp_speech + ORDER, st->fd_synth + 1 + ORDER, 2 * len_subfrm * sizeof(FLOAT32)); + memset(temp_res, 0, 2 * len_subfrm * sizeof(FLOAT32)); + for (i = 0; i < 2 * len_subfrm; i += LEN_SUBFR) { + iusace_compute_lp_residual(lpc, &temp_speech[ORDER + i], &temp_res[i], LEN_SUBFR); + } + memcpy(st->lpd_state.acelp_exc, temp_res, 2 * len_subfrm * sizeof(FLOAT32)); + premph_mem = 0.0f; + iusace_find_weighted_speech(lp_filter_coeff, st->fd_orig + 1 + ORDER, temp_speech + ORDER, + &(st->mem_wsp), 2 * len_subfrm); + memcpy(st->weighted_sig, temp_speech + ORDER + 2 * len_subfrm - 128, 128 * sizeof(FLOAT32)); + memcpy(pstr_scratch->p_wsig_buf, st->weighted_sig, 128 * sizeof(FLOAT32)); + for (i = 0; i < 2 * len_subfrm; i += len_subfrm) { + iusace_decim2_fir_filter(&temp_speech[i + ORDER], len_subfrm, st->mem_lp_decim2, + pstr_scratch->p_fir_sig_buf); + memcpy(temp_speech + ORDER + i / OPL_DECIM, temp_speech + ORDER + i, + (len_subfrm / OPL_DECIM) * sizeof(FLOAT32)); + } + memcpy(wsp_prev_buf, temp_speech + ORDER + 2 * len_subfrm / OPL_DECIM - MAX_PITCH / OPL_DECIM, + (WORD32)((MAX_PITCH / OPL_DECIM) * sizeof(FLOAT32))); + iusace_highpass_prev_wsp(st, temp_speech, pitch_max); + } + memcpy(isp_curr_q, st->isp_old_q, ORDER * sizeof(FLOAT32)); + memcpy(st->isp_old_q, &isp_curr_q[NUM_FRAMES * ORDER], ORDER * sizeof(FLOAT32)); + + for (i = 0; i < NUM_FRAMES; i++) { + iusace_find_weighted_speech( + &lp_filter_coeff[i * (num_sbfrm_per_supfrm / NUM_FRAMES) * (ORDER + 1)], + &speech[i * len_subfrm], &pstr_scratch->p_wsig_buf[i * len_subfrm], &(st->mem_wsp), + len_subfrm); + memcpy(p_wsp_prev_buf, &pstr_scratch->p_wsig_buf[i * len_subfrm], + len_subfrm * sizeof(FLOAT32)); + + iusace_decim2_fir_filter(p_wsp_prev_buf, len_subfrm, st->mem_lp_decim2, + pstr_scratch->p_fir_sig_buf); + range_pitch_search = 2 * LEN_SUBFR; + if (num_subfrm < 4) { + range_pitch_search = 3 * LEN_SUBFR; + } + + iusace_open_loop_search(p_wsp_prev_buf, (pitch_min / OPL_DECIM) + 1, pitch_max / OPL_DECIM, + range_pitch_search / OPL_DECIM, &ol_pitch_lag[i * 2], st); + + if (st->ol_gain > 0.6) { + st->prev_pitch_med = iusace_get_ol_lag_median(ol_pitch_lag[i * 2], st->prev_ol_lags); + st->ada_w = 1.0; + } else { + st->ada_w = st->ada_w * 0.9f; + } + if (st->ada_w < 0.8) { + st->ol_wght_flg = 0; + } else { + st->ol_wght_flg = 1; + } + + max_corr = 0.0f; + p = &p_wsp_prev_buf[0]; + p1 = p_wsp_prev_buf - ol_pitch_lag[i * 2]; + for (j = 0; j < range_pitch_search / OPL_DECIM; j++) { + max_corr += *p++ * *p1++; + } + + t0 = 0.01f; + p = p_wsp_prev_buf - ol_pitch_lag[i * 2]; + for (j = 0; j < range_pitch_search / OPL_DECIM; j++, p++) { + t0 += *p * *p; + } + t0 = (FLOAT32)(1.0 / sqrt(t0)); + norm_corr[i * 2] = max_corr * t0; + + energy = 0.01f; + for (j = 0; j < range_pitch_search / OPL_DECIM; j++) { + energy += p_wsp_prev_buf[j] * p_wsp_prev_buf[j]; + } + energy = (FLOAT32)(1.0 / sqrt(energy)); + norm_corr[i * 2] *= energy; + + if (num_subfrm < 4) { + ol_pitch_lag[(i * 2) + 1] = ol_pitch_lag[i * 2]; + norm_corr[(i * 2) + 1] = norm_corr[i * 2]; + } else { + iusace_open_loop_search(p_wsp_prev_buf + ((2 * LEN_SUBFR) / OPL_DECIM), + (pitch_min / OPL_DECIM) + 1, pitch_max / OPL_DECIM, + (2 * LEN_SUBFR) / OPL_DECIM, &ol_pitch_lag[(i * 2) + 1], st); + + if (st->ol_gain > 0.6) { + st->prev_pitch_med = + iusace_get_ol_lag_median(ol_pitch_lag[(i * 2) + 1], st->prev_ol_lags); + st->ada_w = 1.0; + } else { + st->ada_w = st->ada_w * 0.9f; + } + if (st->ada_w < 0.8) { + st->ol_wght_flg = 0; + } else { + st->ol_wght_flg = 1; + } + max_corr = 0.0f; + p = p_wsp_prev_buf + (2 * LEN_SUBFR) / OPL_DECIM; + p1 = p_wsp_prev_buf + ((2 * LEN_SUBFR) / OPL_DECIM) - ol_pitch_lag[(i * 2) + 1]; + for (j = 0; j < (2 * LEN_SUBFR) / OPL_DECIM; j++) { + max_corr += *p++ * *p1++; + } + + t0 = 0.01f; + p = p_wsp_prev_buf + ((2 * LEN_SUBFR) / OPL_DECIM) - ol_pitch_lag[(i * 2) + 1]; + for (j = 0; j < (2 * LEN_SUBFR) / OPL_DECIM; j++, p++) { + t0 += *p * *p; + } + t0 = (FLOAT32)(1.0 / sqrt(t0)); + norm_corr[(i * 2) + 1] = max_corr * t0; + + energy = 0.01f; + for (j = 0; j < (2 * LEN_SUBFR) / OPL_DECIM; j++) { + energy += p_wsp_prev_buf[((2 * LEN_SUBFR) / OPL_DECIM) + j] * + p_wsp_prev_buf[((2 * LEN_SUBFR) / OPL_DECIM) + j]; + } + energy = (FLOAT32)(1.0 / sqrt(energy)); + norm_corr[(i * 2) + 1] *= energy; + } + + memmove(wsp_prev_buf, &wsp_prev_buf[len_subfrm / OPL_DECIM], + (WORD32)((MAX_PITCH / OPL_DECIM) * sizeof(FLOAT32))); + } + + memcpy(lpd_state[0], &st->lpd_state, sizeof(*lpd_state[0])); + + ssnr_1024 = 0; + + for (i1 = 0; i1 < 2; i1++) { + ssnr_512 = 0; + for (i2 = 0; i2 < 2; i2++) { + k = (i1 * 2) + i2; + p_params = acelp_tcx_params + (k * MAX_NUM_TCX_PRM_PER_DIV); + + iusace_interpolation_lsp_params(&isp_curr_q[k * ORDER], &isp_curr_q[(k + 1) * ORDER], + lp_filter_coeff_q, st->num_subfrm); + + memcpy(lpd_state[k + 1], lpd_state[k], sizeof(*lpd_state[0])); + + iusace_acelp_encode( + &lp_filter_coeff[k * (num_sbfrm_per_supfrm / 4) * (ORDER + 1)], lp_filter_coeff_q, + &speech[k * st->len_subfrm], &pstr_scratch->p_wsig_buf[k * st->len_subfrm], + &pstr_scratch->p_synth_buf[k * st->len_subfrm], + &pstr_scratch->p_wsyn_buf[k * st->len_subfrm], *codec_mode, lpd_state[k + 1], + st->len_subfrm, norm_corr[k * 2], norm_corr[(k * 2) + 1], ol_pitch_lag[k * 2], + ol_pitch_lag[(k * 2) + 1], pit_adj, p_params, pstr_scratch); + + mem_wsyn = lpd_state[k]->mem_wsyn; + + iusace_find_weighted_speech(&lp_filter_coeff[k * (num_sbfrm_per_supfrm / 4) * (ORDER + 1)], + &pstr_scratch->p_synth_buf[k * LEN_FRAME], + pstr_scratch->p_temp_wsyn_buf, &mem_wsyn, LEN_FRAME); + + lpd_state[k + 1]->mem_wsyn = mem_wsyn; + + ssnr_256 = iusace_cal_segsnr(&pstr_scratch->p_wsig_buf[k * LEN_FRAME], + pstr_scratch->p_temp_wsyn_buf, LEN_FRAME, LEN_SUBFR); + + mode[k] = 0; + num_tcx_param[k] = 0; + + iusace_lpc_coef_gen(&isp_curr_q[k * ORDER], &isp_curr_q[(k + 1) * ORDER], lp_filter_coeff_q, + st->num_subfrm, ORDER); + + memcpy(lpd_state_temp, lpd_state[k], sizeof(*lpd_state[0])); + + + iusace_tcx_fac_encode(usac_data, + &lp_filter_coeff[k * (num_sbfrm_per_supfrm / 4) * (ORDER + 1)], + lp_filter_coeff_q, &speech[k * st->len_subfrm], st->len_subfrm, + num_bits_tcx, lpd_state_temp, prm_tcx, &num_params, + ch_idx, k); + + mem_wsyn = lpd_state[k]->mem_wsyn; + + iusace_find_weighted_speech(&lp_filter_coeff[k * (num_sbfrm_per_supfrm / 4) * (ORDER + 1)], + pstr_scratch->p_synth_tcx_buf, pstr_scratch->p_temp_wsyn_buf, + &mem_wsyn, LEN_FRAME); + + lpd_state_temp->mem_wsyn = mem_wsyn; + + tmp_ssnr = iusace_cal_segsnr(&pstr_scratch->p_wsig_buf[k * LEN_FRAME], + pstr_scratch->p_temp_wsyn_buf, LEN_FRAME, LEN_SUBFR); + + if (tmp_ssnr > ssnr_256) { + ssnr_256 = tmp_ssnr; + mode[k] = 1; + num_tcx_param[k] = num_params; + memcpy(lpd_state[k + 1], lpd_state_temp, sizeof(*lpd_state[0])); + + memcpy(&pstr_scratch->p_synth_buf[(k * st->len_subfrm) - 128], + pstr_scratch->p_synth_tcx_buf - 128, (st->len_subfrm + 128) * sizeof(FLOAT32)); + + memcpy(&pstr_scratch->p_wsyn_buf[(k * st->len_subfrm) - 128], + pstr_scratch->p_wsyn_tcx_buf - 128, (st->len_subfrm + 128) * sizeof(FLOAT32)); + + memcpy(p_params, prm_tcx, NUM_TCX20_PRM * sizeof(WORD32)); + } + ssnr_512 += 0.50f * ssnr_256; + } + + k = i1 * 2; + + p_params = acelp_tcx_params + (k * MAX_NUM_TCX_PRM_PER_DIV); + + iusace_lpc_coef_gen(&isp_curr_q[2 * i1 * ORDER], &isp_curr_q[(2 * i1 + 2) * ORDER], + lp_filter_coeff_q, (num_sbfrm_per_supfrm / 2), ORDER); + + memcpy(lpd_state_temp, lpd_state[2 * i1], sizeof(*lpd_state[0])); + iusace_tcx_fac_encode(usac_data, + &lp_filter_coeff[2 * i1 * (num_sbfrm_per_supfrm / 4) * (ORDER + 1)], + lp_filter_coeff_q, &speech[2 * i1 * st->len_subfrm], 2 * st->len_subfrm, + 2 * num_bits_tcx, lpd_state_temp, prm_tcx, &num_params, + ch_idx, 2 * i1); + + mem_wsyn = lpd_state[2 * i1]->mem_wsyn; + + iusace_find_weighted_speech( + &lp_filter_coeff[2 * i1 * (num_sbfrm_per_supfrm / 4) * (ORDER + 1)], + pstr_scratch->p_synth_tcx_buf, pstr_scratch->p_temp_wsyn_buf, &mem_wsyn, LEN_FRAME * 2); + + lpd_state_temp->mem_wsyn = mem_wsyn; + + tmp_ssnr = iusace_cal_segsnr(&pstr_scratch->p_wsig_buf[2 * i1 * LEN_FRAME], + pstr_scratch->p_temp_wsyn_buf, LEN_FRAME * 2, LEN_SUBFR); + + if (tmp_ssnr > ssnr_512) { + ssnr_512 = tmp_ssnr; + for (i = 0; i < 2; i++) { + mode[k + i] = 2; + num_tcx_param[k + i] = num_params; + } + memcpy(lpd_state[k + 2], lpd_state_temp, sizeof(*lpd_state[0])); + + memcpy(&pstr_scratch->p_synth_buf[(2 * i1 * st->len_subfrm) - 128], + pstr_scratch->p_synth_tcx_buf - 128, ((2 * st->len_subfrm) + 128) * sizeof(FLOAT32)); + memcpy(&pstr_scratch->p_wsyn_buf[(2 * i1 * st->len_subfrm) - 128], + pstr_scratch->p_wsyn_tcx_buf - 128, ((2 * st->len_subfrm) + 128) * sizeof(FLOAT32)); + memcpy(p_params, prm_tcx, NUM_TCX40_PRM * sizeof(WORD32)); + } + ssnr_1024 += 0.50f * ssnr_512; + } + + k = 0; + + p_params = acelp_tcx_params + (k * MAX_NUM_TCX_PRM_PER_DIV); + + iusace_lpc_coef_gen(&isp_curr_q[k * ORDER], &isp_curr_q[(k + 4) * ORDER], lp_filter_coeff_q, + num_sbfrm_per_supfrm, ORDER); + + memcpy(lpd_state_temp, lpd_state[k], sizeof(*lpd_state[0])); + + iusace_tcx_fac_encode(usac_data, &lp_filter_coeff[k * (num_sbfrm_per_supfrm / 4) * (ORDER + 1)], + lp_filter_coeff_q, &speech[k * st->len_subfrm], 4 * st->len_subfrm, + 4 * num_bits_tcx, lpd_state_temp, prm_tcx, &num_params, + ch_idx, k); + + mem_wsyn = lpd_state[k]->mem_wsyn; + + iusace_find_weighted_speech(&lp_filter_coeff[k * (num_sbfrm_per_supfrm / 4) * (ORDER + 1)], + pstr_scratch->p_synth_tcx_buf, pstr_scratch->p_temp_wsyn_buf, + &mem_wsyn, LEN_FRAME * 4); + + lpd_state_temp->mem_wsyn = mem_wsyn; + + tmp_ssnr = iusace_cal_segsnr(&pstr_scratch->p_wsig_buf[k * LEN_FRAME], + pstr_scratch->p_temp_wsyn_buf, LEN_FRAME * 4, LEN_SUBFR); + + if (tmp_ssnr > ssnr_1024) { + for (i = 0; i < 4; i++) { + mode[k + i] = 3; + num_tcx_param[k + i] = num_params; + } + memcpy(lpd_state[k + 4], lpd_state_temp, sizeof(*lpd_state[0])); + + memcpy(&pstr_scratch->p_synth_buf[(k * st->len_subfrm) - 128], + pstr_scratch->p_synth_tcx_buf - 128, ((4 * st->len_subfrm) + 128) * sizeof(FLOAT32)); + memcpy(&pstr_scratch->p_wsyn_buf[(k * st->len_subfrm) - 128], + pstr_scratch->p_wsyn_tcx_buf - 128, ((4 * st->len_subfrm) + 128) * sizeof(FLOAT32)); + memcpy(p_params, prm_tcx, NUM_TCX80_PRM * sizeof(WORD32)); + } + memcpy(&st->lpd_state, lpd_state[4], sizeof(*lpd_state[4])); + + memcpy(st->weighted_sig, pstr_scratch->p_wsig_buf + (st->len_frame), 128 * sizeof(FLOAT32)); + memcpy(st->prev_wsp, wsp_prev_buf, (len * sizeof(FLOAT32))); + + return; +} + +IA_ERRORCODE iusace_lpd_frm_enc(ia_usac_data_struct *usac_data, WORD32 *mod_out, + WORD32 const usac_independency_flg, + WORD32 len_frame, + WORD32 i_ch, ia_bit_buf_struct *pstr_it_bit_buff) { + WORD32 i; + WORD32 len_next_high_rate = (LEN_NEXT_HIGH_RATE * len_frame) / LEN_SUPERFRAME; + WORD32 len_lpc0 = (LEN_LPC0 * len_frame) / LEN_SUPERFRAME; + FLOAT32 *input_data = &usac_data->td_in_buf[i_ch][len_next_high_rate]; + ia_usac_td_encoder_struct *td_encoder = usac_data->td_encoder[i_ch]; + WORD32 fscale = usac_data->td_encoder[i_ch]->fscale; + WORD32 first_lpd_flag = (usac_data->core_mode_prev[i_ch] == CORE_MODE_FD); + FLOAT32 *speech_buf = usac_data->speech_buf; + FLOAT32 *ptr_scratch_buf = usac_data->str_scratch.p_lpd_frm_enc_scratch; + FLOAT32 *speech, *new_speech; + WORD32 mode_buf[1 + NUM_FRAMES] = {0}, *mode; + WORD32 num_tcx_params[NUM_FRAMES] = {0}; + WORD32 len_subfrm; + + len_subfrm = td_encoder->len_subfrm; + + if (usac_data->core_mode_prev[i_ch] == CORE_MODE_FD) { + iusace_reset_td_enc(usac_data->td_encoder[i_ch]); + + FLOAT32 *in_data = usac_data->td_in_prev_buf[i_ch]; + FLOAT32 *ptr_speech = usac_data->speech_buf; + WORD32 length = len_next_high_rate + len_lpc0; + ia_usac_td_encoder_struct *st = usac_data->td_encoder[i_ch]; + memcpy(ptr_speech, in_data, length * sizeof(FLOAT32)); + + iusace_highpass_50hz_12k8(ptr_speech, length, st->mem_sig_in, st->fscale); + + iusace_apply_preemph(ptr_speech, PREEMPH_FILT_FAC, length, &(st->mem_preemph)); + memcpy(st->old_speech_pe + ORDER, ptr_speech, length * sizeof(FLOAT32)); + } + + if (first_lpd_flag) { + td_encoder->prev_mode = -1; + } + + mode = mode_buf + 1; + mode[-1] = td_encoder->prev_mode; + fscale = (fscale * len_subfrm) / LEN_FRAME; + + new_speech = speech_buf + ORDER + (LEN_NEXT_HIGH_RATE * len_subfrm) / LEN_FRAME; + speech = speech_buf + ORDER; + if (first_lpd_flag) { + new_speech += (LEN_LPC0 * len_subfrm) / LEN_FRAME; + speech += (LEN_LPC0 * len_subfrm) / LEN_FRAME; + } + memcpy(new_speech, input_data, td_encoder->len_frame * sizeof(FLOAT32)); + + iusace_highpass_50hz_12k8(new_speech, td_encoder->len_frame, td_encoder->mem_sig_in, fscale); + iusace_apply_preemph(new_speech, PREEMPH_FILT_FAC, td_encoder->len_frame, + &(td_encoder->mem_preemph)); + + if (first_lpd_flag) { + memcpy(speech_buf, td_encoder->old_speech_pe, + ((ORDER + (((LEN_NEXT_HIGH_RATE + LEN_LPC0) * len_subfrm) / LEN_FRAME))) * + sizeof(FLOAT32)); + for (i = 0; i < (len_subfrm + 1); i++) { + ptr_scratch_buf[i] = speech[-len_subfrm - 1 + i]; + } + iusace_apply_deemph(ptr_scratch_buf, PREEMPH_FILT_FAC, len_subfrm + 1, &ptr_scratch_buf[0]); + memcpy(td_encoder->lpd_state.tcx_mem, &ptr_scratch_buf[len_subfrm - 128 + 1], + 128 * sizeof(FLOAT32)); + } else { + memcpy(speech_buf, td_encoder->old_speech_pe, + ((ORDER + ((LEN_NEXT_HIGH_RATE * len_subfrm) / LEN_FRAME))) * sizeof(FLOAT32)); + } + + iusace_core_lpd_encode(usac_data, speech, mode, num_tcx_params, i_ch); + + if (first_lpd_flag) { + memcpy(td_encoder->old_speech_pe, + &speech_buf[(td_encoder->len_frame) + (LEN_LPC0 * len_subfrm) / LEN_FRAME], + (ORDER + ((LEN_NEXT_HIGH_RATE * len_subfrm) / LEN_FRAME)) * sizeof(FLOAT32)); + } else { + memcpy(td_encoder->old_speech_pe, &speech_buf[(td_encoder->len_frame)], + (ORDER + ((LEN_NEXT_HIGH_RATE * len_subfrm) / LEN_FRAME)) * sizeof(FLOAT32)); + } + + iusace_encode_fac_params(mode, num_tcx_params, usac_data, usac_independency_flg, + pstr_it_bit_buff, i_ch); + + td_encoder->prev_mode = (WORD16)mode[3]; + + memcpy(mod_out, mode, 4 * sizeof(WORD32)); + return 0; +} diff --git a/encoder/iusace_lpd_rom.c b/encoder/iusace_lpd_rom.c new file mode 100644 index 0000000..242204a --- /dev/null +++ b/encoder/iusace_lpd_rom.c @@ -0,0 +1,417 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include "ixheaac_type_def.h" +#include "iusace_cnst.h" + +const WORD32 iusace_acelp_core_numbits_1024[NUM_ACELP_CORE_MODES] = { + (WORD32)(9.6 * 80), (WORD32)(11.2 * 80), (WORD32)(12.8 * 80), + (WORD32)(14.4 * 80), (WORD32)(16.0 * 80), (WORD32)(18.4 * 80)}; + +const FLOAT32 iusace_sin_window_96[96] = { + 0.008181F, 0.024541F, 0.040895F, 0.057237F, 0.073565F, 0.089872F, 0.106156F, 0.122411F, + 0.138633F, 0.154818F, 0.170962F, 0.187060F, 0.203108F, 0.219101F, 0.235036F, 0.250908F, + 0.266713F, 0.282446F, 0.298104F, 0.313682F, 0.329176F, 0.344581F, 0.359895F, 0.375112F, + 0.390229F, 0.405241F, 0.420145F, 0.434936F, 0.449611F, 0.464166F, 0.478596F, 0.492898F, + 0.507068F, 0.521103F, 0.534998F, 0.548749F, 0.562354F, 0.575808F, 0.589108F, 0.602251F, + 0.615232F, 0.628048F, 0.640696F, 0.653173F, 0.665475F, 0.677598F, 0.689541F, 0.701298F, + 0.712868F, 0.724247F, 0.735432F, 0.746420F, 0.757209F, 0.767795F, 0.778175F, 0.788346F, + 0.798307F, 0.808054F, 0.817585F, 0.826897F, 0.835987F, 0.844854F, 0.853494F, 0.861906F, + 0.870087F, 0.878035F, 0.885748F, 0.893224F, 0.900461F, 0.907457F, 0.914210F, 0.920718F, + 0.926979F, 0.932993F, 0.938756F, 0.944269F, 0.949528F, 0.954533F, 0.959283F, 0.963776F, + 0.968011F, 0.971987F, 0.975702F, 0.979156F, 0.982349F, 0.985278F, 0.987943F, 0.990344F, + 0.992480F, 0.994350F, 0.995953F, 0.997290F, 0.998361F, 0.999163F, 0.999699F, 0.999967F}; + +const FLOAT32 iusace_sin_window_128[128] = { + 0.006136F, 0.018407F, 0.030675F, 0.042938F, 0.055195F, 0.067444F, 0.079682F, 0.091909F, + 0.104122F, 0.116319F, 0.128498F, 0.140658F, 0.152797F, 0.164913F, 0.177004F, 0.189069F, + 0.201105F, 0.213110F, 0.225084F, 0.237024F, 0.248928F, 0.260794F, 0.272621F, 0.284408F, + 0.296151F, 0.307850F, 0.319502F, 0.331106F, 0.342661F, 0.354164F, 0.365613F, 0.377007F, + 0.388345F, 0.399624F, 0.410843F, 0.422000F, 0.433094F, 0.444122F, 0.455084F, 0.465977F, + 0.476799F, 0.487550F, 0.498228F, 0.508830F, 0.519356F, 0.529804F, 0.540172F, 0.550458F, + 0.560662F, 0.570781F, 0.580814F, 0.590760F, 0.600617F, 0.610383F, 0.620057F, 0.629638F, + 0.639124F, 0.648514F, 0.657807F, 0.667000F, 0.676093F, 0.685084F, 0.693971F, 0.702755F, + 0.711432F, 0.720003F, 0.728464F, 0.736817F, 0.745058F, 0.753187F, 0.761202F, 0.769103F, + 0.776888F, 0.784557F, 0.792107F, 0.799537F, 0.806848F, 0.814036F, 0.821103F, 0.828045F, + 0.834863F, 0.841555F, 0.848120F, 0.854558F, 0.860867F, 0.867046F, 0.873095F, 0.879012F, + 0.884797F, 0.890449F, 0.895966F, 0.901349F, 0.906596F, 0.911706F, 0.916679F, 0.921514F, + 0.926210F, 0.930767F, 0.935184F, 0.939459F, 0.943593F, 0.947586F, 0.951435F, 0.955141F, + 0.958703F, 0.962121F, 0.965394F, 0.968522F, 0.971504F, 0.974339F, 0.977028F, 0.979570F, + 0.981964F, 0.984210F, 0.986308F, 0.988258F, 0.990058F, 0.991710F, 0.993212F, 0.994565F, + 0.995767F, 0.996820F, 0.997723F, 0.998476F, 0.999078F, 0.999529F, 0.999831F, 0.999981F}; + +const FLOAT32 iusace_sin_window_192[192] = { + 0.004091F, 0.012272F, 0.020452F, 0.028630F, 0.036807F, 0.044982F, 0.053153F, 0.061321F, + 0.069484F, 0.077643F, 0.085797F, 0.093945F, 0.102087F, 0.110222F, 0.118350F, 0.126469F, + 0.134581F, 0.142683F, 0.150776F, 0.158858F, 0.166930F, 0.174991F, 0.183040F, 0.191077F, + 0.199101F, 0.207111F, 0.215108F, 0.223091F, 0.231058F, 0.239010F, 0.246946F, 0.254866F, + 0.262768F, 0.270653F, 0.278520F, 0.286368F, 0.294197F, 0.302006F, 0.309795F, 0.317563F, + 0.325310F, 0.333036F, 0.340739F, 0.348419F, 0.356076F, 0.363709F, 0.371317F, 0.378901F, + 0.386459F, 0.393992F, 0.401498F, 0.408978F, 0.416430F, 0.423854F, 0.431249F, 0.438616F, + 0.445954F, 0.453261F, 0.460539F, 0.467785F, 0.475000F, 0.482184F, 0.489335F, 0.496453F, + 0.503538F, 0.510590F, 0.517607F, 0.524590F, 0.531537F, 0.538449F, 0.545325F, 0.552164F, + 0.558967F, 0.565732F, 0.572459F, 0.579148F, 0.585798F, 0.592409F, 0.598980F, 0.605511F, + 0.612002F, 0.618451F, 0.624859F, 0.631226F, 0.637550F, 0.643832F, 0.650070F, 0.656265F, + 0.662416F, 0.668522F, 0.674584F, 0.680601F, 0.686572F, 0.692497F, 0.698376F, 0.704208F, + 0.709993F, 0.715731F, 0.721420F, 0.727062F, 0.732654F, 0.738198F, 0.743692F, 0.749136F, + 0.754531F, 0.759874F, 0.765167F, 0.770409F, 0.775599F, 0.780737F, 0.785823F, 0.790857F, + 0.795837F, 0.800764F, 0.805638F, 0.810457F, 0.815223F, 0.819933F, 0.824589F, 0.829190F, + 0.833735F, 0.838225F, 0.842658F, 0.847035F, 0.851355F, 0.855618F, 0.859824F, 0.863973F, + 0.868063F, 0.872096F, 0.876070F, 0.879986F, 0.883842F, 0.887640F, 0.891378F, 0.895056F, + 0.898674F, 0.902233F, 0.905731F, 0.909168F, 0.912544F, 0.915860F, 0.919114F, 0.922306F, + 0.925437F, 0.928506F, 0.931513F, 0.934457F, 0.937339F, 0.940158F, 0.942914F, 0.945607F, + 0.948237F, 0.950803F, 0.953306F, 0.955745F, 0.958120F, 0.960431F, 0.962677F, 0.964859F, + 0.966976F, 0.969029F, 0.971017F, 0.972940F, 0.974798F, 0.976590F, 0.978317F, 0.979979F, + 0.981575F, 0.983105F, 0.984570F, 0.985969F, 0.987301F, 0.988568F, 0.989768F, 0.990903F, + 0.991970F, 0.992972F, 0.993907F, 0.994775F, 0.995577F, 0.996313F, 0.996981F, 0.997583F, + 0.998118F, 0.998586F, 0.998988F, 0.999322F, 0.999590F, 0.999791F, 0.999925F, 0.999992F}; + +const FLOAT32 iusace_sin_window_256[256] = { + 0.00306796F, 0.00920375F, 0.01533921F, 0.02147408F, 0.02760815F, 0.03374117F, 0.03987293F, + 0.04600318F, 0.05213170F, 0.05825826F, 0.06438263F, 0.07050457F, 0.07662386F, 0.08274026F, + 0.08885355F, 0.09496350F, 0.10106986F, 0.10717242F, 0.11327095F, 0.11936521F, 0.12545498F, + 0.13154003F, 0.13762012F, 0.14369503F, 0.14976453F, 0.15582840F, 0.16188639F, 0.16793829F, + 0.17398387F, 0.18002290F, 0.18605515F, 0.19208040F, 0.19809841F, 0.20410897F, 0.21011184F, + 0.21610680F, 0.22209362F, 0.22807208F, 0.23404196F, 0.24000302F, 0.24595505F, 0.25189782F, + 0.25783110F, 0.26375468F, 0.26966833F, 0.27557182F, 0.28146494F, 0.28734746F, 0.29321916F, + 0.29907983F, 0.30492923F, 0.31076715F, 0.31659338F, 0.32240768F, 0.32820984F, 0.33399965F, + 0.33977688F, 0.34554132F, 0.35129276F, 0.35703096F, 0.36275572F, 0.36846683F, 0.37416406F, + 0.37984721F, 0.38551605F, 0.39117038F, 0.39680999F, 0.40243465F, 0.40804416F, 0.41363831F, + 0.41921689F, 0.42477968F, 0.43032648F, 0.43585708F, 0.44137127F, 0.44686884F, 0.45234959F, + 0.45781330F, 0.46325978F, 0.46868882F, 0.47410021F, 0.47949376F, 0.48486925F, 0.49022648F, + 0.49556526F, 0.50088538F, 0.50618665F, 0.51146885F, 0.51673180F, 0.52197529F, 0.52719913F, + 0.53240313F, 0.53758708F, 0.54275078F, 0.54789406F, 0.55301671F, 0.55811853F, 0.56319934F, + 0.56825895F, 0.57329717F, 0.57831380F, 0.58330865F, 0.58828155F, 0.59323230F, 0.59816071F, + 0.60306660F, 0.60794978F, 0.61281008F, 0.61764731F, 0.62246128F, 0.62725182F, 0.63201874F, + 0.63676186F, 0.64148101F, 0.64617601F, 0.65084668F, 0.65549285F, 0.66011434F, 0.66471098F, + 0.66928259F, 0.67382900F, 0.67835004F, 0.68284555F, 0.68731534F, 0.69175926F, 0.69617713F, + 0.70056879F, 0.70493408F, 0.70927283F, 0.71358487F, 0.71787005F, 0.72212819F, 0.72635916F, + 0.73056277F, 0.73473888F, 0.73888732F, 0.74300795F, 0.74710061F, 0.75116513F, 0.75520138F, + 0.75920919F, 0.76318842F, 0.76713891F, 0.77106052F, 0.77495311F, 0.77881651F, 0.78265060F, + 0.78645521F, 0.79023022F, 0.79397548F, 0.79769084F, 0.80137617F, 0.80503133F, 0.80865618F, + 0.81225059F, 0.81581441F, 0.81934752F, 0.82284978F, 0.82632106F, 0.82976123F, 0.83317016F, + 0.83654773F, 0.83989379F, 0.84320824F, 0.84649094F, 0.84974177F, 0.85296060F, 0.85614733F, + 0.85930182F, 0.86242396F, 0.86551362F, 0.86857071F, 0.87159509F, 0.87458665F, 0.87754529F, + 0.88047089F, 0.88336334F, 0.88622253F, 0.88904836F, 0.89184071F, 0.89459949F, 0.89732458F, + 0.90001589F, 0.90267332F, 0.90529676F, 0.90788612F, 0.91044129F, 0.91296219F, 0.91544872F, + 0.91790078F, 0.92031828F, 0.92270113F, 0.92504924F, 0.92736253F, 0.92964090F, 0.93188427F, + 0.93409255F, 0.93626567F, 0.93840353F, 0.94050607F, 0.94257320F, 0.94460484F, 0.94660091F, + 0.94856135F, 0.95048607F, 0.95237501F, 0.95422810F, 0.95604525F, 0.95782641F, 0.95957151F, + 0.96128049F, 0.96295327F, 0.96458979F, 0.96619000F, 0.96775384F, 0.96928124F, 0.97077214F, + 0.97222650F, 0.97364425F, 0.97502535F, 0.97636973F, 0.97767736F, 0.97894818F, 0.98018214F, + 0.98137919F, 0.98253930F, 0.98366242F, 0.98474850F, 0.98579751F, 0.98680940F, 0.98778414F, + 0.98872169F, 0.98962202F, 0.99048508F, 0.99131086F, 0.99209931F, 0.99285041F, 0.99356414F, + 0.99424045F, 0.99487933F, 0.99548076F, 0.99604470F, 0.99657115F, 0.99706007F, 0.99751146F, + 0.99792529F, 0.99830154F, 0.99864022F, 0.99894129F, 0.99920476F, 0.99943060F, 0.99961882F, + 0.99976941F, 0.99988235F, 0.99995764F, 0.99999529F}; + +const FLOAT32 iusace_lsf_init[ORDER] = {375.0, 750.0, 1125.0, 1500.0, 1875.0, 2250.0, + 2625.0, 3000.0, 3375.0, 3750.0, 4125.0, 4500.0, + 4875.0, 5250.0, 5625.0, 6000.0}; + +const FLOAT32 iusace_ispold_init[ORDER] = {0.982973f, 0.932472f, 0.850217f, 0.739009f, + 0.602635f, 0.445738f, 0.273663f, 0.092268f, + -0.092268f, -0.273663f, -0.445738f, -0.602635f, + -0.739009f, -0.850217f, -0.932472f, -0.982973f}; + +const FLOAT32 iusace_cos_window_512[512] = { + 0.003067957f, 0.009203754f, 0.015339206f, 0.021474080f, 0.027608145f, 0.033741172f, + 0.039872929f, 0.046003181f, 0.052131705f, 0.058258265f, 0.064382628f, 0.070504576f, + 0.076623864f, 0.082740262f, 0.088853553f, 0.094963498f, 0.101069860f, 0.107172422f, + 0.113270953f, 0.119365215f, 0.125454977f, 0.131540030f, 0.137620121f, 0.143695027f, + 0.149764538f, 0.155828401f, 0.161886394f, 0.167938292f, 0.173983872f, 0.180022895f, + 0.186055154f, 0.192080393f, 0.198098406f, 0.204108968f, 0.210111842f, 0.216106802f, + 0.222093627f, 0.228072077f, 0.234041959f, 0.240003020f, 0.245955050f, 0.251897812f, + 0.257831097f, 0.263754666f, 0.269668311f, 0.275571823f, 0.281464934f, 0.287347466f, + 0.293219149f, 0.299079835f, 0.304929227f, 0.310767144f, 0.316593379f, 0.322407693f, + 0.328209847f, 0.333999664f, 0.339776874f, 0.345541328f, 0.351292759f, 0.357030958f, + 0.362755716f, 0.368466824f, 0.374164075f, 0.379847199f, 0.385516047f, 0.391170382f, + 0.396809995f, 0.402434647f, 0.408044159f, 0.413638324f, 0.419216901f, 0.424779683f, + 0.430326492f, 0.435857087f, 0.441371262f, 0.446868837f, 0.452349573f, 0.457813293f, + 0.463259786f, 0.468688816f, 0.474100202f, 0.479493767f, 0.484869242f, 0.490226477f, + 0.495565265f, 0.500885367f, 0.506186664f, 0.511468828f, 0.516731799f, 0.521975279f, + 0.527199149f, 0.532403111f, 0.537587047f, 0.542750776f, 0.547894061f, 0.553016722f, + 0.558118522f, 0.563199341f, 0.568258941f, 0.573297143f, 0.578313768f, 0.583308637f, + 0.588281572f, 0.593232274f, 0.598160684f, 0.603066623f, 0.607949793f, 0.612810075f, + 0.617647290f, 0.622461259f, 0.627251804f, 0.632018745f, 0.636761844f, 0.641481042f, + 0.646176040f, 0.650846660f, 0.655492842f, 0.660114348f, 0.664710999f, 0.669282615f, + 0.673829019f, 0.678350031f, 0.682845533f, 0.687315345f, 0.691759229f, 0.696177125f, + 0.700568795f, 0.704934061f, 0.709272802f, 0.713584840f, 0.717870057f, 0.722128212f, + 0.726359129f, 0.730562747f, 0.734738886f, 0.738887310f, 0.743007958f, 0.747100592f, + 0.751165152f, 0.755201399f, 0.759209216f, 0.763188422f, 0.767138898f, 0.771060526f, + 0.774953127f, 0.778816521f, 0.782650590f, 0.786455214f, 0.790230215f, 0.793975472f, + 0.797690868f, 0.801376164f, 0.805031359f, 0.808656156f, 0.812250614f, 0.815814435f, + 0.819347501f, 0.822849810f, 0.826321065f, 0.829761207f, 0.833170176f, 0.836547732f, + 0.839893818f, 0.843208253f, 0.846490920f, 0.849741757f, 0.852960587f, 0.856147349f, + 0.859301805f, 0.862423956f, 0.865513623f, 0.868570685f, 0.871595085f, 0.874586642f, + 0.877545297f, 0.880470872f, 0.883363366f, 0.886222541f, 0.889048338f, 0.891840696f, + 0.894599497f, 0.897324562f, 0.900015891f, 0.902673304f, 0.905296743f, 0.907886088f, + 0.910441279f, 0.912962198f, 0.915448725f, 0.917900801f, 0.920318305f, 0.922701120f, + 0.925049245f, 0.927362502f, 0.929640889f, 0.931884289f, 0.934092522f, 0.936265647f, + 0.938403547f, 0.940506041f, 0.942573190f, 0.944604814f, 0.946600914f, 0.948561370f, + 0.950486064f, 0.952374995f, 0.954228103f, 0.956045270f, 0.957826436f, 0.959571540f, + 0.961280465f, 0.962953269f, 0.964589775f, 0.966189981f, 0.967753828f, 0.969281256f, + 0.970772147f, 0.972226501f, 0.973644257f, 0.975025356f, 0.976369739f, 0.977677345f, + 0.978948176f, 0.980182111f, 0.981379211f, 0.982539296f, 0.983662426f, 0.984748483f, + 0.985797524f, 0.986809373f, 0.987784147f, 0.988721669f, 0.989621997f, 0.990485072f, + 0.991310835f, 0.992099285f, 0.992850423f, 0.993564129f, 0.994240463f, 0.994879305f, + 0.995480776f, 0.996044695f, 0.996571124f, 0.997060061f, 0.997511446f, 0.997925282f, + 0.998301566f, 0.998640239f, 0.998941302f, 0.999204755f, 0.999430597f, 0.999618828f, + 0.999769390f, 0.999882340f, 0.999957621f, 0.999995291f, 0.999995291f, 0.999957621f, + 0.999882340f, 0.999769390f, 0.999618828f, 0.999430597f, 0.999204755f, 0.998941302f, + 0.998640239f, 0.998301566f, 0.997925282f, 0.997511446f, 0.997060061f, 0.996571124f, + 0.996044695f, 0.995480776f, 0.994879305f, 0.994240463f, 0.993564129f, 0.992850423f, + 0.992099285f, 0.991310835f, 0.990485072f, 0.989621997f, 0.988721669f, 0.987784147f, + 0.986809373f, 0.985797524f, 0.984748483f, 0.983662426f, 0.982539296f, 0.981379211f, + 0.980182111f, 0.978948176f, 0.977677345f, 0.976369739f, 0.975025356f, 0.973644257f, + 0.972226501f, 0.970772147f, 0.969281256f, 0.967753828f, 0.966189981f, 0.964589775f, + 0.962953269f, 0.961280465f, 0.959571540f, 0.957826436f, 0.956045270f, 0.954228103f, + 0.952374995f, 0.950486064f, 0.948561370f, 0.946600914f, 0.944604814f, 0.942573190f, + 0.940506041f, 0.938403547f, 0.936265647f, 0.934092522f, 0.931884289f, 0.929640889f, + 0.927362502f, 0.925049245f, 0.922701120f, 0.920318305f, 0.917900801f, 0.915448725f, + 0.912962198f, 0.910441279f, 0.907886088f, 0.905296743f, 0.902673304f, 0.900015891f, + 0.897324562f, 0.894599497f, 0.891840696f, 0.889048338f, 0.886222541f, 0.883363366f, + 0.880470872f, 0.877545297f, 0.874586642f, 0.871595085f, 0.868570685f, 0.865513623f, + 0.862423956f, 0.859301805f, 0.856147349f, 0.852960587f, 0.849741757f, 0.846490920f, + 0.843208253f, 0.839893818f, 0.836547732f, 0.833170176f, 0.829761207f, 0.826321065f, + 0.822849810f, 0.819347501f, 0.815814435f, 0.812250614f, 0.808656156f, 0.805031359f, + 0.801376164f, 0.797690868f, 0.793975472f, 0.790230215f, 0.786455214f, 0.782650590f, + 0.778816521f, 0.774953127f, 0.771060526f, 0.767138898f, 0.763188422f, 0.759209216f, + 0.755201399f, 0.751165152f, 0.747100592f, 0.743007958f, 0.738887310f, 0.734738886f, + 0.730562747f, 0.726359129f, 0.722128212f, 0.717870057f, 0.713584840f, 0.709272802f, + 0.704934061f, 0.700568795f, 0.696177125f, 0.691759229f, 0.687315345f, 0.682845533f, + 0.678350031f, 0.673829019f, 0.669282615f, 0.664710999f, 0.660114348f, 0.655492842f, + 0.650846660f, 0.646176040f, 0.641481042f, 0.636761844f, 0.632018745f, 0.627251804f, + 0.622461259f, 0.617647290f, 0.612810075f, 0.607949793f, 0.603066623f, 0.598160684f, + 0.593232274f, 0.588281572f, 0.583308637f, 0.578313768f, 0.573297143f, 0.568258941f, + 0.563199341f, 0.558118522f, 0.553016722f, 0.547894061f, 0.542750776f, 0.537587047f, + 0.532403111f, 0.527199149f, 0.521975279f, 0.516731799f, 0.511468828f, 0.506186664f, + 0.500885367f, 0.495565265f, 0.490226477f, 0.484869242f, 0.479493767f, 0.474100202f, + 0.468688816f, 0.463259786f, 0.457813293f, 0.452349573f, 0.446868837f, 0.441371262f, + 0.435857087f, 0.430326492f, 0.424779683f, 0.419216901f, 0.413638324f, 0.408044159f, + 0.402434647f, 0.396809995f, 0.391170382f, 0.385516047f, 0.379847199f, 0.374164075f, + 0.368466824f, 0.362755716f, 0.357030958f, 0.351292759f, 0.345541328f, 0.339776874f, + 0.333999664f, 0.328209847f, 0.322407693f, 0.316593379f, 0.310767144f, 0.304929227f, + 0.299079835f, 0.293219149f, 0.287347466f, 0.281464934f, 0.275571823f, 0.269668311f, + 0.263754666f, 0.257831097f, 0.251897812f, 0.245955050f, 0.240003020f, 0.234041959f, + 0.228072077f, 0.222093627f, 0.216106802f, 0.210111842f, 0.204108968f, 0.198098406f, + 0.192080393f, 0.186055154f, 0.180022895f, 0.173983872f, 0.167938292f, 0.161886394f, + 0.155828401f, 0.149764538f, 0.143695027f, 0.137620121f, 0.131540030f, 0.125454977f, + 0.119365215f, 0.113270953f, 0.107172422f, 0.101069860f, 0.094963498f, 0.088853553f, + 0.082740262f, 0.076623864f, 0.070504576f, 0.064382628f, 0.058258265f, 0.052131705f, + 0.046003181f, 0.039872929f, 0.033741172f, 0.027608145f, 0.021474080f, 0.015339206f, + 0.009203754f, 0.003067957f}; + +const FLOAT32 iusace_cos_window_448[448] = { + 0.003506235f, 0.010518531f, 0.017530311f, 0.024541229f, 0.031550940f, 0.038559098f, + 0.045565363f, 0.052569386f, 0.059570823f, 0.066569328f, 0.073564567f, 0.080556184f, + 0.087543838f, 0.094527185f, 0.101505890f, 0.108479597f, 0.115447976f, 0.122410677f, + 0.129367352f, 0.136317670f, 0.143261284f, 0.150197864f, 0.157127038f, 0.164048493f, + 0.170961887f, 0.177866876f, 0.184763104f, 0.191650257f, 0.198527992f, 0.205395952f, + 0.212253809f, 0.219101235f, 0.225937888f, 0.232763439f, 0.239577532f, 0.246379837f, + 0.253170043f, 0.259947777f, 0.266712755f, 0.273464620f, 0.280203015f, 0.286927640f, + 0.293638140f, 0.300334215f, 0.307015538f, 0.313681751f, 0.320332527f, 0.326967567f, + 0.333586514f, 0.340189070f, 0.346774876f, 0.353343636f, 0.359895051f, 0.366428733f, + 0.372944415f, 0.379441738f, 0.385920405f, 0.392380118f, 0.398820519f, 0.405241311f, + 0.411642164f, 0.418022811f, 0.424382865f, 0.430722058f, 0.437040091f, 0.443336606f, + 0.449611336f, 0.455863953f, 0.462094128f, 0.468301624f, 0.474486053f, 0.480647177f, + 0.486784667f, 0.492898196f, 0.498987496f, 0.505052269f, 0.511092186f, 0.517107010f, + 0.523096323f, 0.529060006f, 0.534997642f, 0.540908933f, 0.546793640f, 0.552651465f, + 0.558482170f, 0.564285338f, 0.570060790f, 0.575808167f, 0.581527293f, 0.587217808f, + 0.592879415f, 0.598511875f, 0.604114890f, 0.609688222f, 0.615231574f, 0.620744705f, + 0.626227260f, 0.631679058f, 0.637099743f, 0.642489135f, 0.647846937f, 0.653172851f, + 0.658466637f, 0.663728058f, 0.668956876f, 0.674152792f, 0.679315507f, 0.684444845f, + 0.689540565f, 0.694602311f, 0.699629962f, 0.704623163f, 0.709581733f, 0.714505374f, + 0.719393909f, 0.724247098f, 0.729064643f, 0.733846307f, 0.738591909f, 0.743301213f, + 0.747973979f, 0.752609909f, 0.757208824f, 0.761770546f, 0.766294777f, 0.770781398f, + 0.775230050f, 0.779640555f, 0.784012794f, 0.788346410f, 0.792641282f, 0.796897233f, + 0.801113904f, 0.805291235f, 0.809428990f, 0.813526869f, 0.817584813f, 0.821602523f, + 0.825579822f, 0.829516530f, 0.833412468f, 0.837267399f, 0.841081142f, 0.844853580f, + 0.848584414f, 0.852273524f, 0.855920792f, 0.859525919f, 0.863088787f, 0.866609156f, + 0.870086968f, 0.873521984f, 0.876914084f, 0.880263031f, 0.883568645f, 0.886830866f, + 0.890049458f, 0.893224299f, 0.896355212f, 0.899442017f, 0.902484655f, 0.905482829f, + 0.908436537f, 0.911345541f, 0.914209783f, 0.917029023f, 0.919803143f, 0.922532082f, + 0.925215602f, 0.927853703f, 0.930446148f, 0.932992816f, 0.935493588f, 0.937948406f, + 0.940357089f, 0.942719519f, 0.945035577f, 0.947305143f, 0.949528158f, 0.951704502f, + 0.953834057f, 0.955916643f, 0.957952261f, 0.959940791f, 0.961882055f, 0.963776052f, + 0.965622663f, 0.967421770f, 0.969173372f, 0.970877230f, 0.972533405f, 0.974141717f, + 0.975702107f, 0.977214575f, 0.978678942f, 0.980095208f, 0.981463313f, 0.982783079f, + 0.984054565f, 0.985277653f, 0.986452281f, 0.987578392f, 0.988655984f, 0.989684880f, + 0.990665197f, 0.991596758f, 0.992479563f, 0.993313551f, 0.994098663f, 0.994834960f, + 0.995522261f, 0.996160686f, 0.996750057f, 0.997290432f, 0.997781813f, 0.998224080f, + 0.998617291f, 0.998961389f, 0.999256313f, 0.999502122f, 0.999698818f, 0.999846339f, + 0.999944687f, 0.999993861f, 0.999993861f, 0.999944687f, 0.999846339f, 0.999698818f, + 0.999502122f, 0.999256313f, 0.998961389f, 0.998617291f, 0.998224080f, 0.997781813f, + 0.997290432f, 0.996750057f, 0.996160686f, 0.995522261f, 0.994834960f, 0.994098663f, + 0.993313551f, 0.992479563f, 0.991596758f, 0.990665197f, 0.989684880f, 0.988655984f, + 0.987578392f, 0.986452281f, 0.985277653f, 0.984054565f, 0.982783079f, 0.981463313f, + 0.980095208f, 0.978678942f, 0.977214575f, 0.975702107f, 0.974141717f, 0.972533405f, + 0.970877230f, 0.969173372f, 0.967421770f, 0.965622663f, 0.963776052f, 0.961882055f, + 0.959940791f, 0.957952261f, 0.955916643f, 0.953834057f, 0.951704502f, 0.949528158f, + 0.947305143f, 0.945035577f, 0.942719519f, 0.940357089f, 0.937948406f, 0.935493588f, + 0.932992816f, 0.930446148f, 0.927853703f, 0.925215602f, 0.922532082f, 0.919803143f, + 0.917029023f, 0.914209783f, 0.911345541f, 0.908436537f, 0.905482829f, 0.902484655f, + 0.899442017f, 0.896355212f, 0.893224299f, 0.890049458f, 0.886830866f, 0.883568645f, + 0.880263031f, 0.876914084f, 0.873521984f, 0.870086968f, 0.866609156f, 0.863088787f, + 0.859525919f, 0.855920792f, 0.852273524f, 0.848584414f, 0.844853580f, 0.841081142f, + 0.837267399f, 0.833412468f, 0.829516530f, 0.825579822f, 0.821602523f, 0.817584813f, + 0.813526869f, 0.809428990f, 0.805291235f, 0.801113904f, 0.796897233f, 0.792641282f, + 0.788346410f, 0.784012794f, 0.779640555f, 0.775230050f, 0.770781398f, 0.766294777f, + 0.761770546f, 0.757208824f, 0.752609909f, 0.747973979f, 0.743301213f, 0.738591909f, + 0.733846307f, 0.729064643f, 0.724247098f, 0.719393909f, 0.714505374f, 0.709581733f, + 0.704623163f, 0.699629962f, 0.694602311f, 0.689540565f, 0.684444845f, 0.679315507f, + 0.674152792f, 0.668956876f, 0.663728058f, 0.658466637f, 0.653172851f, 0.647846937f, + 0.642489135f, 0.637099743f, 0.631679058f, 0.626227260f, 0.620744705f, 0.615231574f, + 0.609688222f, 0.604114890f, 0.598511875f, 0.592879415f, 0.587217808f, 0.581527293f, + 0.575808167f, 0.570060790f, 0.564285338f, 0.558482170f, 0.552651465f, 0.546793640f, + 0.540908933f, 0.534997642f, 0.529060006f, 0.523096323f, 0.517107010f, 0.511092186f, + 0.505052269f, 0.498987496f, 0.492898196f, 0.486784667f, 0.480647177f, 0.474486053f, + 0.468301624f, 0.462094128f, 0.455863953f, 0.449611336f, 0.443336606f, 0.437040091f, + 0.430722058f, 0.424382865f, 0.418022811f, 0.411642164f, 0.405241311f, 0.398820519f, + 0.392380118f, 0.385920405f, 0.379441738f, 0.372944415f, 0.366428733f, 0.359895051f, + 0.353343636f, 0.346774876f, 0.340189070f, 0.333586514f, 0.326967567f, 0.320332527f, + 0.313681751f, 0.307015538f, 0.300334215f, 0.293638140f, 0.286927640f, 0.280203015f, + 0.273464620f, 0.266712755f, 0.259947777f, 0.253170043f, 0.246379837f, 0.239577532f, + 0.232763439f, 0.225937888f, 0.219101235f, 0.212253809f, 0.205395952f, 0.198527992f, + 0.191650257f, 0.184763104f, 0.177866876f, 0.170961887f, 0.164048493f, 0.157127038f, + 0.150197864f, 0.143261284f, 0.136317670f, 0.129367352f, 0.122410677f, 0.115447976f, + 0.108479597f, 0.101505890f, 0.094527185f, 0.087543838f, 0.080556184f, 0.073564567f, + 0.066569328f, 0.059570823f, 0.052569386f, 0.045565363f, 0.038559098f, 0.031550940f, + 0.024541229f, 0.017530311f, 0.010518531f, 0.003506235f}; + +const FLOAT32 iusace_lag_window[17] = { + 1.0001f, 0.999566371183f, 0.998266612613f, 0.996104103033f, 0.993084457421f, + 0.989215493202f, 0.984507262707f, 0.978971838951f, 0.972623467445f, 0.965478420258f, + 0.957554817200f, 0.948872864246f, 0.939454317093f, 0.929322779179f, 0.918503403664f, + 0.907022833824f, 0.894909143448f, +}; + +const FLOAT32 iusace_res_interp_filter1_4[INTER_LP_FIL_LEN + 4] = { + 0.940000f, 0.856390f, 0.632268f, 0.337560f, 0.059072f, -0.131059f, -0.199393f, -0.158569f, + -0.056359f, 0.047606f, 0.106749f, 0.103705f, 0.052062f, -0.015182f, -0.063705f, -0.073660f, + -0.046497f, -0.000983f, 0.038227f, 0.053143f, 0.040059f, 0.009308f, -0.021674f, -0.037767f, + -0.033186f, -0.013028f, 0.010702f, 0.025901f, 0.026318f, 0.013821f, -0.003645f, -0.016813f, + -0.019855f, -0.012766f, -0.000530f, 0.010080f, 0.014122f, 0.010657f, 0.002594f, -0.005363f, + -0.009344f, -0.008101f, -0.003182f, 0.002330f, 0.005635f, 0.005562f, 0.002844f, -0.000627f, + -0.002993f, -0.003362f, -0.002044f, -0.000116f, 0.001315f, 0.001692f, 0.001151f, 0.000259f, + -0.000417f, -0.000618f, -0.000434f, -0.000133f, 0.000063f, 0.000098f, 0.000048f, 0.000007f, + 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f}; + +/* [b,a] = butter(2, 20.0/(sampling_freq/2), 'high') --> {a1, a2, b1, b2}. + Coeffs a1 and a2 are sign inversed in the table. +*/ +const FLOAT32 iusace_hp20_filter_coeffs[12][4] = { + /* 8000Hz */ + {1.977786483776763f, -0.978030508491796f, -1.977908496134280f, 0.988954248067140f}, + + /* 11025Hz */ + {1.983881041660839f, -0.984009917549517f, -1.983945479605178f, 0.991972739802589f}, + + /* 12000Hz */ + {1.985190657896261f, -0.985299513128215f, -1.985245085512239f, 0.992622542756119f}, + + {1.994446410541927f, -0.994461789075954f, -1.994454099808941f, 0.997227049904470f}, + {1.995970179642829f, -0.995978283057647f, -1.995974231350238f, 0.997987115675119f}, + {1.996297601769122f, -0.996304442992686f, -1.996301022380904f, 0.998150511190452f}, + {1.997223199944181f, -0.997227049911866f, -1.997225124928023f, 0.998612562464012f}, + + /* 44100Hz */ + {1.995970179642829f, -0.995978283057647f, -1.995974231350238f, 0.997987115675119f}, + + /* 48000Hz */ + {1.996297601769122f, -0.996304442992686f, -1.996301022380904f, 0.998150511190452f}, + + /* 64000Hz */ + {1.997223199944181f, -0.997227049911866f, -1.997225124928023f, 0.998612562464012f}, + + /* 88200Hz */ + {1.997985087783538f, -0.997987115677172f, -1.997986101730355f, 0.998993050865178f}, + + /* 96000Hz */ + {1.998148799303698f, -0.998150511191915f, -1.998149655247807f, 0.999074827623903f}, + +}; + +const FLOAT32 iexheaac_cos_window_384[384] = { + 0.0081811396f, 0.0163617316f, 0.0245412285f, 0.0327190828f, 0.0408947472f, 0.0490676743f, + 0.0572373173f, 0.0654031292f, 0.0735645636f, 0.0817210741f, 0.0898721149f, 0.0980171403f, + 0.1061556053f, 0.1142869650f, 0.1224106752f, 0.1305261922f, 0.1386329728f, 0.1467304745f, + 0.1548181551f, 0.1628954734f, 0.1709618888f, 0.1790168613f, 0.1870598518f, 0.1950903220f, + 0.2031077344f, 0.2111115524f, 0.2191012402f, 0.2270762630f, 0.2350360872f, 0.2429801799f, + 0.2509080094f, 0.2588190451f, 0.2667127575f, 0.2745886182f, 0.2824461001f, 0.2902846773f, + 0.2981038250f, 0.3059030201f, 0.3136817404f, 0.3214394653f, 0.3291756756f, 0.3368898534f, + 0.3445814824f, 0.3522500479f, 0.3598950365f, 0.3675159366f, 0.3751122380f, 0.3826834324f, + 0.3902290129f, 0.3977484745f, 0.4052413140f, 0.4127070298f, 0.4201451222f, 0.4275550934f, + 0.4349364474f, 0.4422886902f, 0.4496113297f, 0.4569038756f, 0.4641658400f, 0.4713967368f, + 0.4785960820f, 0.4857633937f, 0.4928981922f, 0.5000000000f, 0.5070683417f, 0.5141027442f, + 0.5211027367f, 0.5280678507f, 0.5349976199f, 0.5418915806f, 0.5487492713f, 0.5555702330f, + 0.5623540092f, 0.5691001459f, 0.5758081914f, 0.5824776969f, 0.5891082158f, 0.5956993045f, + 0.6022505217f, 0.6087614290f, 0.6152315906f, 0.6216605734f, 0.6280479471f, 0.6343932842f, + 0.6406961599f, 0.6469561525f, 0.6531728430f, 0.6593458151f, 0.6654746558f, 0.6715589548f, + 0.6775983050f, 0.6835923020f, 0.6895405447f, 0.6954426350f, 0.7012981778f, 0.7071067812f, + 0.7128680564f, 0.7185816178f, 0.7242470830f, 0.7298640727f, 0.7354322111f, 0.7409511254f, + 0.7464204462f, 0.7518398075f, 0.7572088465f, 0.7625272039f, 0.7677945237f, 0.7730104534f, + 0.7781746438f, 0.7832867492f, 0.7883464276f, 0.7933533403f, 0.7983071521f, 0.8032075315f, + 0.8080541504f, 0.8128466846f, 0.8175848132f, 0.8222682190f, 0.8268965886f, 0.8314696123f, + 0.8359869839f, 0.8404484011f, 0.8448535652f, 0.8492021815f, 0.8534939589f, 0.8577286100f, + 0.8619058515f, 0.8660254038f, 0.8700869911f, 0.8740903416f, 0.8780351874f, 0.8819212643f, + 0.8857483124f, 0.8895160754f, 0.8932243012f, 0.8968727415f, 0.9004611522f, 0.9039892931f, + 0.9074569281f, 0.9108638249f, 0.9142097557f, 0.9174944964f, 0.9207178273f, 0.9238795325f, + 0.9269794005f, 0.9300172237f, 0.9329927988f, 0.9359059268f, 0.9387564125f, 0.9415440652f, + 0.9442686983f, 0.9469301295f, 0.9495281806f, 0.9520626777f, 0.9545334512f, 0.9569403357f, + 0.9592831702f, 0.9615617977f, 0.9637760658f, 0.9659258263f, 0.9680109353f, 0.9700312532f, + 0.9719866448f, 0.9738769793f, 0.9757021300f, 0.9774619749f, 0.9791563962f, 0.9807852804f, + 0.9823485185f, 0.9838460059f, 0.9852776424f, 0.9866433321f, 0.9879429836f, 0.9891765100f, + 0.9903438286f, 0.9914448614f, 0.9924795346f, 0.9934477790f, 0.9943495298f, 0.9951847267f, + 0.9959533136f, 0.9966552393f, 0.9972904567f, 0.9978589232f, 0.9983606009f, 0.9987954562f, + 0.9991634599f, 0.9994645875f, 0.9996988187f, 0.9998661379f, 0.9999665339f, 1.0000000000f, + 0.9999665339f, 0.9998661379f, 0.9996988187f, 0.9994645875f, 0.9991634599f, 0.9987954562f, + 0.9983606009f, 0.9978589232f, 0.9972904567f, 0.9966552393f, 0.9959533136f, 0.9951847267f, + 0.9943495298f, 0.9934477790f, 0.9924795346f, 0.9914448614f, 0.9903438286f, 0.9891765100f, + 0.9879429836f, 0.9866433321f, 0.9852776424f, 0.9838460059f, 0.9823485185f, 0.9807852804f, + 0.9791563962f, 0.9774619749f, 0.9757021300f, 0.9738769793f, 0.9719866448f, 0.9700312532f, + 0.9680109353f, 0.9659258263f, 0.9637760658f, 0.9615617977f, 0.9592831702f, 0.9569403357f, + 0.9545334512f, 0.9520626777f, 0.9495281806f, 0.9469301295f, 0.9442686983f, 0.9415440652f, + 0.9387564125f, 0.9359059268f, 0.9329927988f, 0.9300172237f, 0.9269794005f, 0.9238795325f, + 0.9207178273f, 0.9174944964f, 0.9142097557f, 0.9108638249f, 0.9074569281f, 0.9039892931f, + 0.9004611522f, 0.8968727415f, 0.8932243012f, 0.8895160754f, 0.8857483124f, 0.8819212643f, + 0.8780351874f, 0.8740903416f, 0.8700869911f, 0.8660254038f, 0.8619058515f, 0.8577286100f, + 0.8534939589f, 0.8492021815f, 0.8448535652f, 0.8404484011f, 0.8359869839f, 0.8314696123f, + 0.8268965886f, 0.8222682190f, 0.8175848132f, 0.8128466846f, 0.8080541504f, 0.8032075315f, + 0.7983071521f, 0.7933533403f, 0.7883464276f, 0.7832867492f, 0.7781746438f, 0.7730104534f, + 0.7677945237f, 0.7625272039f, 0.7572088465f, 0.7518398075f, 0.7464204462f, 0.7409511254f, + 0.7354322111f, 0.7298640727f, 0.7242470830f, 0.7185816178f, 0.7128680564f, 0.7071067812f, + 0.7012981778f, 0.6954426350f, 0.6895405447f, 0.6835923020f, 0.6775983050f, 0.6715589548f, + 0.6654746558f, 0.6593458151f, 0.6531728430f, 0.6469561525f, 0.6406961599f, 0.6343932842f, + 0.6280479471f, 0.6216605734f, 0.6152315906f, 0.6087614290f, 0.6022505217f, 0.5956993045f, + 0.5891082158f, 0.5824776969f, 0.5758081914f, 0.5691001459f, 0.5623540092f, 0.5555702330f, + 0.5487492713f, 0.5418915806f, 0.5349976199f, 0.5280678507f, 0.5211027367f, 0.5141027442f, + 0.5070683417f, 0.5000000000f, 0.4928981922f, 0.4857633937f, 0.4785960820f, 0.4713967368f, + 0.4641658400f, 0.4569038756f, 0.4496113297f, 0.4422886902f, 0.4349364474f, 0.4275550934f, + 0.4201451222f, 0.4127070298f, 0.4052413140f, 0.3977484745f, 0.3902290129f, 0.3826834324f, + 0.3751122380f, 0.3675159366f, 0.3598950365f, 0.3522500479f, 0.3445814824f, 0.3368898534f, + 0.3291756756f, 0.3214394653f, 0.3136817404f, 0.3059030201f, 0.2981038250f, 0.2902846773f, + 0.2824461001f, 0.2745886182f, 0.2667127575f, 0.2588190451f, 0.2509080094f, 0.2429801799f, + 0.2350360872f, 0.2270762630f, 0.2191012402f, 0.2111115524f, 0.2031077344f, 0.1950903220f, + 0.1870598518f, 0.1790168613f, 0.1709618888f, 0.1628954734f, 0.1548181551f, 0.1467304745f, + 0.1386329728f, 0.1305261922f, 0.1224106752f, 0.1142869650f, 0.1061556053f, 0.0980171403f, + 0.0898721149f, 0.0817210741f, 0.0735645636f, 0.0654031292f, 0.0572373173f, 0.0490676743f, + 0.0408947472f, 0.0327190828f, 0.0245412285f, 0.0163617316f, 0.0081811396f, 0.0000000000f, +}; diff --git a/encoder/iusace_lpd_rom.h b/encoder/iusace_lpd_rom.h new file mode 100644 index 0000000..084f5d0 --- /dev/null +++ b/encoder/iusace_lpd_rom.h @@ -0,0 +1,39 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +extern const FLOAT32 iusace_lsf_init[ORDER]; +extern const FLOAT32 iusace_sin_window_96[96]; +extern const FLOAT32 iusace_sin_window_128[128]; +extern const FLOAT32 iusace_sin_window_192[192]; +extern const FLOAT32 iusace_sin_window_256[256]; +extern const FLOAT32 iusace_res_interp_filter1_4[INTER_LP_FIL_LEN + 4]; +extern const FLOAT32 iusace_lag_window[17]; +extern const FLOAT32 iusace_lsf_init[ORDER]; +extern const FLOAT32 iusace_ispold_init[ORDER]; +extern const FLOAT32 iusace_cos_window_512[512]; +extern const FLOAT32 iusace_cos_window_448[448]; +extern const WORD32 iusace_acelp_core_numbits_1024[NUM_ACELP_CORE_MODES]; +extern const FLOAT32 iusace_acelp_quant_gain_table[]; +extern const UWORD8 iusace_acelp_ipos[36]; +extern const FLOAT32 iexheaac_cos_window_384[384]; +extern const FLOAT32 iusace_hp20_filter_coeffs[12][4]; +extern const FLOAT32 iusace_ol_corr_weight[518]; +extern const FLOAT32 iusace_interp4_1[17]; diff --git a/encoder/iusace_lpd_utils.c b/encoder/iusace_lpd_utils.c new file mode 100644 index 0000000..96a8395 --- /dev/null +++ b/encoder/iusace_lpd_utils.c @@ -0,0 +1,593 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include +#include "ixheaac_type_def.h" +#include "ixheaace_adjust_threshold_data.h" +#include "iusace_bitbuffer.h" + +/* DRC */ +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" +#include "impd_drc_uni_drc_eq.h" +#include "impd_drc_uni_drc_filter_bank.h" +#include "impd_drc_gain_enc.h" +#include "impd_drc_struct_def.h" + +#include "iusace_cnst.h" +#include "iusace_tns_usac.h" +#include "iusace_psy_mod.h" +#include "iusace_fd_qc_util.h" +#include "iusace_tns_usac.h" +#include "iusace_config.h" +#include "iusace_arith_enc.h" +#include "iusace_fd_quant.h" +#include "iusace_block_switch_const.h" +#include "iusace_block_switch_struct_def.h" +#include "iusace_ms.h" +#include "iusace_signal_classifier.h" +#include "ixheaace_sbr_header.h" +#include "ixheaace_config.h" +#include "ixheaace_asc_write.h" +#include "iusace_main.h" +#include "iusace_func_prototypes.h" +#include "iusace_lpd_rom.h" +#include "ixheaace_common_utils.h" + +WORD32 ia_get_sample_rate(WORD32 sample_rate) { + if (92017 <= sample_rate) { + return 11; + } + if (75132 <= sample_rate) { + return 10; + } + if (55426 <= sample_rate) { + return 9; + } + if (46009 <= sample_rate) { + return 8; + } + if (37566 <= sample_rate) { + return 7; + } + if (27713 <= sample_rate) { + return 6; + } + if (23004 <= sample_rate) { + return 5; + } + if (18783 <= sample_rate) { + return 4; + } + if (13856 <= sample_rate) { + return 3; + } + if (11502 <= sample_rate) { + return 2; + } + if (9391 <= sample_rate) { + return 1; + } + return 0; +} + +VOID iusace_write_bits2buf(WORD32 value, WORD32 no_of_bits, WORD16 *bitstream) { + WORD16 *pt_bitstream; + WORD32 i; + pt_bitstream = bitstream + no_of_bits; + for (i = 0; i < no_of_bits; i++) { + *--pt_bitstream = (WORD16)(value & MASK); + value >>= 1; + } + return; +} + +WORD32 iusace_get_num_params(WORD32 *qn) { + return 2 + ((qn[0] > 0) ? 9 : 0) + ((qn[1] > 0) ? 9 : 0); +} + +FLOAT32 iusace_cal_segsnr(FLOAT32 *sig1, FLOAT32 *sig2, WORD16 len, WORD16 nseg) { + FLOAT32 snr = 0.0f; + FLOAT32 signal, noise, error, fac; + WORD16 i, j; + for (i = 0; i < len; i += nseg) { + signal = 1e-6f; + noise = 1e-6f; + for (j = 0; j < nseg; j++) { + signal += (*sig1) * (*sig1); + error = *sig1++ - *sig2++; + noise += error * error; + } + snr += (FLOAT32)log10((FLOAT64)(signal / noise)); + } + fac = ((FLOAT32)(10 * nseg)) / (FLOAT32)len; + snr = fac * snr; + if (snr < -99.0f) { + snr = -99.0f; + } + return (snr); +} + +VOID iusace_highpass_50hz_12k8(FLOAT32 *signal, WORD32 lg, FLOAT32 *mem, WORD32 fscale) { + WORD32 i; + WORD32 sr_idx = 0; + FLOAT32 x0, x1, x2, y0, y1, y2; + const FLOAT32 *a = NULL, *b = NULL; + + y1 = mem[0]; + y2 = mem[1]; + x0 = mem[2]; + x1 = mem[3]; + sr_idx = ia_get_sample_rate(fscale); + a = &iusace_hp20_filter_coeffs[sr_idx][0]; + b = &iusace_hp20_filter_coeffs[sr_idx][2]; + + for (i = 0; i < lg; i++) { + x2 = x1; + x1 = x0; + x0 = signal[i]; + y0 = (y1 * a[0]) + (y2 * a[1]) + (x0 * b[1]) + (x1 * b[0]) + (x2 * b[1]); + signal[i] = y0; + y2 = y1; + y1 = y0; + } + + mem[0] = ((y1 > 1e-10) | (y1 < -1e-10)) ? y1 : 0; + mem[1] = ((y2 > 1e-10) | (y2 < -1e-10)) ? y2 : 0; + mem[2] = ((x0 > 1e-10) | (x0 < -1e-10)) ? x0 : 0; + mem[3] = ((x1 > 1e-10) | (x1 < -1e-10)) ? x1 : 0; +} + +VOID iusace_apply_preemph(FLOAT32 *signal, FLOAT32 factor, WORD32 length, FLOAT32 *mem) { + WORD32 i; + FLOAT32 temp; + temp = signal[length - 1]; + for (i = length - 1; i > 0; i--) { + signal[i] = signal[i] - factor * signal[i - 1]; + } + signal[0] -= factor * (*mem); + *mem = temp; +} + +VOID iusace_apply_deemph(FLOAT32 *signal, FLOAT32 factor, WORD32 length, FLOAT32 *mem) { + WORD32 i; + signal[0] = signal[0] + factor * (*mem); + for (i = 1; i < length; i++) { + signal[i] = signal[i] + factor * signal[i - 1]; + } + *mem = signal[length - 1]; + if ((*mem < 1e-10) & (*mem > -1e-10)) { + *mem = 0; + } +} + +VOID iusace_synthesis_tool_float(FLOAT32 *a, FLOAT32 *x, FLOAT32 *y, WORD32 l, FLOAT32 *mem, + FLOAT32 *scratch_synth_tool) { + FLOAT32 s; + FLOAT32 *yy; + WORD32 i, j; + memcpy(scratch_synth_tool, mem, ORDER * sizeof(FLOAT32)); + yy = &scratch_synth_tool[ORDER]; + for (i = 0; i < l; i++) { + s = x[i]; + for (j = 1; j <= ORDER; j += 4) { + s -= a[j] * yy[i - j]; + s -= a[j + 1] * yy[i - (j + 1)]; + s -= a[j + 2] * yy[i - (j + 2)]; + s -= a[j + 3] * yy[i - (j + 3)]; + } + yy[i] = s; + y[i] = s; + } +} + +VOID iusace_compute_lp_residual(FLOAT32 *a, FLOAT32 *x, FLOAT32 *y, WORD32 l) { + FLOAT32 s; + WORD32 i; + for (i = 0; i < l; i++) { + s = x[i]; + s += a[1] * x[i - 1]; + s += a[2] * x[i - 2]; + s += a[3] * x[i - 3]; + s += a[4] * x[i - 4]; + s += a[5] * x[i - 5]; + s += a[6] * x[i - 6]; + s += a[7] * x[i - 7]; + s += a[8] * x[i - 8]; + s += a[9] * x[i - 9]; + s += a[10] * x[i - 10]; + s += a[11] * x[i - 11]; + s += a[12] * x[i - 12]; + s += a[13] * x[i - 13]; + s += a[14] * x[i - 14]; + s += a[15] * x[i - 15]; + s += a[16] * x[i - 16]; + y[i] = s; + } +} + +VOID iusace_convolve(FLOAT32 *signal, FLOAT32 *wsynth_filter_ir, FLOAT32 *conv_out) { + FLOAT32 temp; + WORD32 i, n; + for (n = 0; n < LEN_SUBFR; n += 2) { + temp = 0.0f; + for (i = 0; i <= n; i++) { + temp += signal[i] * wsynth_filter_ir[n - i]; + } + conv_out[n] = temp; + temp = 0.0f; + for (i = 0; i <= (n + 1); i += 2) { + temp += signal[i] * wsynth_filter_ir[(n + 1) - i]; + temp += signal[i + 1] * wsynth_filter_ir[n - i]; + } + conv_out[n + 1] = temp; + } +} + +VOID iusace_autocorr_plus(FLOAT32 *speech, FLOAT32 *auto_corr_vector, WORD32 window_len, + const FLOAT32 *lp_analysis_win, FLOAT32 *temp_aut_corr) { + FLOAT32 val; + WORD16 i, j; + for (i = 0; i < window_len; i++) { + temp_aut_corr[i] = speech[i] * lp_analysis_win[i]; + } + for (i = 0; i <= ORDER; i++) { + val = 0.0f; + for (j = 0; j < window_len - i; j++) { + val += temp_aut_corr[j] * temp_aut_corr[j + i]; + } + auto_corr_vector[i] = val; + } + if (auto_corr_vector[0] < 1.0) { + auto_corr_vector[0] = 1.0; + } +} + +static VOID iusace_get_norm_correlation(FLOAT32 *exc, FLOAT32 *xn, FLOAT32 *wsyn_filt_ir, + WORD32 min_interval, WORD32 max_interval, + FLOAT32 *norm_corr) { + WORD32 i, j, k; + FLOAT32 filt_prev_exc[LEN_SUBFR]; + FLOAT32 energy_filt_exc, corr, norm; + k = -min_interval; + + iusace_convolve(&exc[k], wsyn_filt_ir, filt_prev_exc); + + for (i = min_interval; i <= max_interval; i++) { + corr = 0.0F; + energy_filt_exc = 0.01F; + for (j = 0; j < LEN_SUBFR; j++) { + corr += xn[j] * filt_prev_exc[j]; + energy_filt_exc += filt_prev_exc[j] * filt_prev_exc[j]; + } + + norm = (FLOAT32)(1.0f / sqrt(energy_filt_exc)); + norm_corr[i - min_interval] = corr * norm; + + if (i != max_interval) { + k--; + for (j = LEN_SUBFR - 1; j > 0; j--) { + filt_prev_exc[j] = filt_prev_exc[j - 1] + exc[k] * wsyn_filt_ir[j]; + } + filt_prev_exc[0] = exc[k]; + } + } +} + +static FLOAT32 iusace_corr_interpolate(FLOAT32 *x, WORD32 fraction) { + FLOAT32 interpol_value, *x1, *x2; + const FLOAT32 *p1_interp4_1_table, *p2_interp4_1_table; + if (fraction < 0) { + fraction += 4; + x--; + } + x1 = &x[0]; + x2 = &x[1]; + p1_interp4_1_table = &iusace_interp4_1[fraction]; + p2_interp4_1_table = &iusace_interp4_1[4 - fraction]; + interpol_value = x1[0] * p1_interp4_1_table[0] + x2[0] * p2_interp4_1_table[0]; + interpol_value += x1[-1] * p1_interp4_1_table[4] + x2[1] * p2_interp4_1_table[4]; + interpol_value += x1[-2] * p1_interp4_1_table[8] + x2[2] * p2_interp4_1_table[8]; + interpol_value += x1[-3] * p1_interp4_1_table[12] + x2[3] * p2_interp4_1_table[12]; + + return interpol_value; +} + +VOID iusace_open_loop_search(FLOAT32 *wsp, WORD32 min_pitch_lag, WORD32 max_pitch_lag, + WORD32 num_frame, WORD32 *ol_pitch_lag, + ia_usac_td_encoder_struct *st) { + WORD32 i, j, k; + FLOAT32 r, corr, energy1, energy2, corr_max = -1.0e23f; + const FLOAT32 *p1_ol_cw_table, *p2_ol_cw_table; + FLOAT32 *data_a, *data_b, *hp_wsp, *p, *p1; + + p1_ol_cw_table = &iusace_ol_corr_weight[453]; + p2_ol_cw_table = &iusace_ol_corr_weight[259 + max_pitch_lag - st->prev_pitch_med]; + *ol_pitch_lag = 0; + for (i = max_pitch_lag; i > min_pitch_lag; i--) { + p = &wsp[0]; + p1 = &wsp[-i]; + corr = 0.0; + for (j = 0; j < num_frame; j += 2) { + corr += p[j] * p1[j]; + corr += p[j + 1] * p1[j + 1]; + } + corr *= *p1_ol_cw_table--; + if ((st->prev_pitch_med > 0) && (st->ol_wght_flg == 1)) { + corr *= *p2_ol_cw_table--; + } + if (corr >= corr_max) { + corr_max = corr; + *ol_pitch_lag = i; + } + } + data_a = st->hp_ol_ltp_mem; + data_b = st->hp_ol_ltp_mem + HP_ORDER; + hp_wsp = st->prev_hp_wsp + max_pitch_lag; + for (k = 0; k < num_frame; k++) { + data_b[0] = data_b[1]; + data_b[1] = data_b[2]; + data_b[2] = data_b[3]; + data_b[HP_ORDER] = wsp[k]; + r = data_b[0] * 0.83787057505665F; + r += data_b[1] * -2.50975570071058F; + r += data_b[2] * 2.50975570071058F; + r += data_b[3] * -0.83787057505665F; + r -= data_a[0] * -2.64436711600664F; + r -= data_a[1] * 2.35087386625360F; + r -= data_a[2] * -0.70001156927424F; + data_a[2] = data_a[1]; + data_a[1] = data_a[0]; + data_a[0] = r; + hp_wsp[k] = r; + } + p = &hp_wsp[0]; + p1 = &hp_wsp[-(*ol_pitch_lag)]; + corr = 0.0F; + energy1 = 0.0F; + energy2 = 0.0F; + for (j = 0; j < num_frame; j++) { + energy1 += p1[j] * p1[j]; + energy2 += p[j] * p[j]; + corr += p[j] * p1[j]; + } + st->ol_gain = (FLOAT32)(corr / (sqrt(energy1 * energy2) + 1e-5)); + memmove(st->prev_hp_wsp, &st->prev_hp_wsp[num_frame], max_pitch_lag * sizeof(FLOAT32)); +} + +WORD32 iusace_get_ol_lag_median(WORD32 prev_ol_lag, WORD32 *prev_ol_lags) { + WORD32 sorted_ol_lags_out[NUM_OPEN_LOOP_LAGS + 1] = {0}; + WORD32 i, j, idx, val; + WORD32 num_lags = NUM_OPEN_LOOP_LAGS; + for (i = NUM_OPEN_LOOP_LAGS - 1; i > 0; i--) { + prev_ol_lags[i] = prev_ol_lags[i - 1]; + } + prev_ol_lags[0] = prev_ol_lag; + for (i = 0; i < NUM_OPEN_LOOP_LAGS; i++) { + sorted_ol_lags_out[i + 1] = prev_ol_lags[i]; + } + + idx = (NUM_OPEN_LOOP_LAGS >> 1) + 1; + for (;;) { + if (idx > 1) { + val = sorted_ol_lags_out[--idx]; + } else { + val = sorted_ol_lags_out[num_lags]; + sorted_ol_lags_out[num_lags] = sorted_ol_lags_out[1]; + if (--num_lags == 1) { + sorted_ol_lags_out[1] = val; + break; + } + } + i = idx; + j = idx << 1; + while (j <= num_lags) { + if (j < num_lags && sorted_ol_lags_out[j] < sorted_ol_lags_out[j + 1]) { + ++j; + } + if (val < sorted_ol_lags_out[j]) { + sorted_ol_lags_out[i] = sorted_ol_lags_out[j]; + i = j; + j *= 2; + } else { + j = num_lags + 1; + } + } + sorted_ol_lags_out[i] = val; + } + + return sorted_ol_lags_out[OPEN_LOOP_LAG_MEDIAN]; +} + +VOID iusace_closed_loop_search(FLOAT32 *exc, FLOAT32 *xn, FLOAT32 *wsyn_filt_ir, + WORD32 search_range_min, WORD32 search_range_max, WORD32 *pit_frac, + WORD32 is_first_subfrm, WORD32 min_pitch_lag_res1_2, + WORD32 min_pitch_lag_res_1, WORD32 *pitch_lag_out) { + WORD32 i, fraction, step; + FLOAT32 corr_vector[15 + 2 * LEN_INTERPOL1 + 1] = {0}; + FLOAT32 corr_max, temp; + FLOAT32 *p_norm_corr_vector; + WORD32 min_interval, max_interval; + min_interval = search_range_min - LEN_INTERPOL1; + max_interval = search_range_max + LEN_INTERPOL1; + p_norm_corr_vector = &corr_vector[0]; + iusace_get_norm_correlation(exc, xn, wsyn_filt_ir, min_interval, max_interval, + p_norm_corr_vector); + + corr_max = p_norm_corr_vector[LEN_INTERPOL1]; + *pitch_lag_out = search_range_min; + for (i = search_range_min + 1; i <= search_range_max; i++) { + if (p_norm_corr_vector[i - search_range_min + LEN_INTERPOL1] > corr_max) { + corr_max = p_norm_corr_vector[i - search_range_min + LEN_INTERPOL1]; + *pitch_lag_out = i; + } + } + if ((is_first_subfrm == 0) && (*pitch_lag_out >= min_pitch_lag_res_1)) { + *pit_frac = 0; + } else { + step = 1; + fraction = -3; + if (((is_first_subfrm == 0) && (*pitch_lag_out >= min_pitch_lag_res1_2)) || + (min_pitch_lag_res1_2 == TMIN)) { + step = 2; + fraction = -2; + } + if (*pitch_lag_out == search_range_min) { + fraction = 0; + } + corr_max = iusace_corr_interpolate( + &p_norm_corr_vector[(*pitch_lag_out) - search_range_min + LEN_INTERPOL1], fraction); + for (i = (fraction + step); i <= 3; i += step) { + temp = iusace_corr_interpolate( + &p_norm_corr_vector[(*pitch_lag_out) - search_range_min + LEN_INTERPOL1], i); + if (temp > corr_max) { + corr_max = temp; + fraction = i; + } + } + if (fraction < 0) { + fraction += 4; + (*pitch_lag_out) -= 1; + } + *pit_frac = fraction; + } +} + +VOID iusace_decim2_fir_filter(FLOAT32 *signal, WORD32 length, FLOAT32 *mem, + FLOAT32 *scratch_fir_sig_buf) { + FLOAT32 *sig_buf = scratch_fir_sig_buf; + FLOAT32 temp; + WORD32 i, j; + memcpy(sig_buf, mem, DECIM2_FIR_FILT_MEM_SIZE * sizeof(FLOAT32)); + memcpy(sig_buf + DECIM2_FIR_FILT_MEM_SIZE, signal, length * sizeof(FLOAT32)); + for (i = 0; i < DECIM2_FIR_FILT_MEM_SIZE; i++) { + mem[i] = ((signal[length - DECIM2_FIR_FILT_MEM_SIZE + i] > 1e-10) || + (signal[length - DECIM2_FIR_FILT_MEM_SIZE + i] < -1e-10)) + ? signal[length - DECIM2_FIR_FILT_MEM_SIZE + i] + : 0; + } + for (i = 0, j = 0; i < length; i += 2, j++) { + temp = sig_buf[i] * 0.13F; + temp += sig_buf[i + 1] * 0.23F; + temp += sig_buf[i + 2] * 0.28F; +#ifdef _WIN32 +#pragma warning(suppress : 6385) +#endif + temp += sig_buf[i + 3] * 0.23F; + temp += sig_buf[i + 4] * 0.13F; + signal[j] = temp; + } +} + +FLOAT32 iusace_calc_sq_gain(FLOAT32 *x, WORD32 num_bits, WORD32 length, + FLOAT32 *scratch_sq_gain_en) { + WORD32 i, j, k; + FLOAT32 gain, ener, temp, target, factor, offset; + FLOAT32 *en = scratch_sq_gain_en; + + for (i = 0; i < length; i += 4) { + ener = 0.01f; + for (j = i; j < i + 4; j++) { + ener += x[j] * x[j]; + } + + temp = (FLOAT32)log10(ener); + en[i / 4] = 9.0f + 10.0f * temp; + } + + target = (6.0f / 4.0f) * (FLOAT32)(num_bits - (length / 16)); + + factor = 128.0f; + offset = factor; + + for (k = 0; k < 10; k++) { + factor *= 0.5f; + offset -= factor; + ener = 0.0f; + for (i = 0; i < length / 4; i++) { + temp = en[i] - offset; + + if (temp > 3.0f) { + ener += temp; + } + } + if (ener > target) { + offset += factor; + } + } + + gain = (FLOAT32)pow(10.0f, offset / 20.0f); + + return (gain); +} + +VOID iusace_lpc_coef_gen(FLOAT32 *lsf_old, FLOAT32 *lsf_new, FLOAT32 *a, WORD32 nb_subfr, + WORD32 m) { + FLOAT32 lsf[ORDER] = {0}, *ptr_a; + FLOAT32 inc, fnew, fold; + WORD32 i = 0; + + ptr_a = a; + + inc = 1.0f / (FLOAT32)nb_subfr; + fnew = 0.5f - (0.5f * inc); + fold = 1.0f - fnew; + for (i = 0; i < m; i++) { + lsf[i] = (lsf_old[i] * fold) + (lsf_new[i] * fnew); + } + iusace_lsp_to_lp_conversion(lsf, ptr_a); + ptr_a += (m + 1); + iusace_lsp_to_lp_conversion(lsf_old, ptr_a); + ptr_a += (m + 1); + iusace_lsp_to_lp_conversion(lsf_new, ptr_a); + + return; +} + +VOID iusace_interpolation_lsp_params(FLOAT32 *lsp_old, FLOAT32 *lsp_new, FLOAT32 *lp_flt_coff_a, + WORD32 nb_subfr) { + FLOAT32 lsp[ORDER]; + FLOAT32 factor; + WORD32 i, k; + FLOAT32 x_plus_y, x_minus_y; + + factor = 1.0f / (FLOAT32)nb_subfr; + + x_plus_y = 0.5f * factor; + + for (k = 0; k < nb_subfr; k++) { + x_minus_y = 1.0f - x_plus_y; + for (i = 0; i < ORDER; i++) { + lsp[i] = (lsp_old[i] * x_minus_y) + (lsp_new[i] * x_plus_y); + } + x_plus_y += factor; + + iusace_lsp_to_lp_conversion(lsp, lp_flt_coff_a); + + lp_flt_coff_a += (ORDER + 1); + } + + iusace_lsp_to_lp_conversion(lsp_new, lp_flt_coff_a); + + return; +} diff --git a/encoder/iusace_main.h b/encoder/iusace_main.h new file mode 100644 index 0000000..7f63bd9 --- /dev/null +++ b/encoder/iusace_main.h @@ -0,0 +1,125 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once + +typedef struct { + WORD32 window_size_samples[MAX_TIME_CHANNELS]; + WORD32 usac_independency_flag_interval; + WORD32 usac_independency_flag_count; + WORD32 usac_independency_flag; + WORD32 frame_count; + WORD32 core_mode[MAX_TIME_CHANNELS]; + WORD32 core_mode_prev[MAX_TIME_CHANNELS]; + WORD32 core_mode_prev_copy[MAX_TIME_CHANNELS]; + WORD32 core_mode_next[MAX_TIME_CHANNELS]; + WORD32 core_mode_copy[MAX_TIME_CHANNELS]; + ia_block_switch_ctrl block_switch_ctrl[MAX_TIME_CHANNELS]; + ia_classification_struct str_sig_class_data; + FLOAT32 td_in_buf[MAX_TIME_CHANNELS][LEN_SUPERFRAME + LEN_NEXT_HIGH_RATE]; + FLOAT32 td_in_prev_buf[MAX_TIME_CHANNELS][LEN_SUPERFRAME + LEN_NEXT_HIGH_RATE + LEN_LPC0]; + FLOAT32 speech_buf[LEN_TOTAL_HIGH_RATE + LEN_LPC0]; + FLOAT32 synth_buf[ORDER + LEN_SUPERFRAME]; + WORD32 param_buf[(NUM_FRAMES * MAX_NUM_TCX_PRM_PER_DIV) + NUM_LPC_PRM]; + ia_usac_td_encoder_struct *td_encoder[MAX_TIME_CHANNELS]; + WORD32 total_nbbits[MAX_TIME_CHANNELS]; + WORD32 FD_nbbits_fac[MAX_TIME_CHANNELS]; + WORD32 num_td_fac_bits[MAX_TIME_CHANNELS]; + WORD32 td_bitrate[MAX_TIME_CHANNELS]; + WORD32 acelp_core_mode[MAX_TIME_CHANNELS]; + WORD32 max_bitreservoir_bits; + WORD32 available_bitreservoir_bits; + ia_drc_enc_state str_drc_state; + WORD32 num_sbr_bits; + ia_ms_info_struct str_ms_info[MAX_TIME_CHANNELS]; + WORD32 pred_coef_re[MAX_TIME_CHANNELS][MAX_SHORT_WINDOWS][MAX_SFB_LONG], + pred_coef_im[MAX_TIME_CHANNELS][MAX_SHORT_WINDOWS][MAX_SFB_LONG]; + WORD32 pred_coef_re_prev[MAX_TIME_CHANNELS][MAX_SFB_LONG], + pred_coef_im_prev[MAX_TIME_CHANNELS][MAX_SFB_LONG]; + /* Temporary buffers for bitstream writing function when computing static bits */ + WORD32 temp_pred_coef_re_prev[MAX_TIME_CHANNELS][MAX_SFB_LONG], + temp_pred_coef_im_prev[MAX_TIME_CHANNELS][MAX_SFB_LONG]; + WORD32 pred_dir_idx[MAX_TIME_CHANNELS]; + WORD32 cplx_pred_all[MAX_TIME_CHANNELS]; + WORD32 cplx_pred_used[MAX_TIME_CHANNELS][MAX_SHORT_WINDOWS][MAX_SFB_LONG]; + WORD32 delta_code_time[MAX_TIME_CHANNELS]; + WORD32 complex_coef[MAX_TIME_CHANNELS]; + FLOAT64 *ptr_dmx_re_save[MAX_TIME_CHANNELS]; /*For saving previous frame MDCT down-mix */ + FLOAT64 *ptr_dmx_im[MAX_TIME_CHANNELS]; + FLOAT64 arr_dmx_im[MAX_TIME_CHANNELS][(FRAME_LEN_LONG + FRAME_LEN_LONG / 8)]; + FLOAT64 arr_dmx_save_float[MAX_TIME_CHANNELS][(FRAME_LEN_LONG + FRAME_LEN_LONG / 8)]; + FLOAT64 left_chan_save[MAX_TIME_CHANNELS][(FRAME_LEN_LONG + FRAME_LEN_LONG / 8)]; + FLOAT64 right_chan_save[MAX_TIME_CHANNELS][(FRAME_LEN_LONG + FRAME_LEN_LONG / 8)]; + + ia_tns_info *pstr_tns_info[MAX_TIME_CHANNELS]; + WORD32 common_window[MAX_TIME_CHANNELS]; + WORD32 noise_offset[MAX_TIME_CHANNELS]; + WORD32 noise_level[MAX_TIME_CHANNELS]; + + ia_usac_quant_info_struct str_quant_info[MAX_TIME_CHANNELS]; + WORD32 noise_filling[MAX_TIME_CHANNELS]; + ia_psy_mod_struct str_psy_mod; + ia_qc_main_struct str_qc_main; + FLOAT64 *ptr_time_data[MAX_TIME_CHANNELS]; + FLOAT64 *ptr_look_ahead_time_data[MAX_TIME_CHANNELS]; + FLOAT64 *spectral_line_vector[MAX_TIME_CHANNELS]; + // Pre-/post- twiddle portions of MDCT use two times ccfl of this buffer, hence size of second + // argument is 2 * pstr_config->ccfl + FLOAT64 mdst_spectrum[MAX_TIME_CHANNELS][2 * FRAME_LEN_LONG]; + FLOAT64 *ptr_2frame_time_data[MAX_TIME_CHANNELS]; + WORD16 td_serial_out[MAX_TIME_CHANNELS][NBITS_MAX]; + WORD16 fac_out_stream[MAX_TIME_CHANNELS][NBITS_MAX]; + FLOAT64 overlap_buf[MAX_TIME_CHANNELS][2 * FRAME_LEN_LONG]; + WORD32 channel_elem_type[MAX_TIME_CHANNELS]; + WORD32 channel_elem_idx[MAX_TIME_CHANNELS]; + WORD32 num_ext_elements; + WORD32 ext_type[MAX_EXTENSION_PAYLOADS]; + UWORD8 ext_elem_config_payload[MAX_EXTENSION_PAYLOADS][MAX_EXTENSION_PAYLOAD_LEN]; + UWORD32 ext_elem_config_len[MAX_EXTENSION_PAYLOADS]; + iusace_scratch_mem str_scratch; +} ia_usac_data_struct; + +typedef struct { + ia_usac_lpd_state_struct lpd_state[6]; + ia_usac_lpd_state_struct flpd_state[6]; + +} ia_usac_lpd_scratch; + +IA_ERRORCODE iusace_enc_init(ia_usac_encoder_config_struct *ptr_usac_config, + ixheaace_audio_specific_config_struct *pstr_asc, + ia_usac_data_struct *pstr_state); + +IA_ERRORCODE iusace_quantize_spec(ia_sfb_params_struct *pstr_sfb_prms, + WORD32 usac_independancy_flag, WORD32 num_chans, + ia_usac_data_struct *ptr_usac_data, + ia_usac_encoder_config_struct *ptr_usac_config, WORD32 chn, + WORD32 ele_id); + +IA_ERRORCODE iusace_grouping(ia_sfb_params_struct *pstr_sfb_prms, WORD32 num_chans, + ia_usac_data_struct *ptr_usac_data, + ia_usac_encoder_config_struct *ptr_usac_config, WORD32 chn, + WORD32 ele_id); + +IA_ERRORCODE iusace_stereo_proc(ia_sfb_params_struct *pstr_sfb_prms, + WORD32 usac_independancy_flag, ia_usac_data_struct *ptr_usac_data, + ia_usac_encoder_config_struct *ptr_usac_config, WORD32 chn); + +VOID iusace_classification(ia_classification_struct *pstr_sig_class, + iusace_scratch_mem *pstr_scratch, WORD32 ccfl); diff --git a/encoder/iusace_ms.c b/encoder/iusace_ms.c new file mode 100644 index 0000000..1822402 --- /dev/null +++ b/encoder/iusace_ms.c @@ -0,0 +1,142 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include "ixheaac_type_def.h" +#include "ixheaac_constants.h" +#include "iusace_cnst.h" +#include "iusace_bitbuffer.h" +#include "iusace_tns_usac.h" +#include "iusace_psy_mod.h" +#include "ixheaac_basic_ops32.h" +#include "ixheaac_basic_ops40.h" +#include "ixheaac_basic_ops.h" + +VOID iusace_ms_apply(ia_psy_mod_data_struct *pstr_psy_data, FLOAT64 *ptr_spec_left, + FLOAT64 *ptr_spec_right, WORD32 *ms_select, + WORD32 ms_used[MAX_SHORT_WINDOWS][MAX_SFB_LONG], const WORD32 sfb_count, + const WORD32 sfb_per_group, const WORD32 max_sfb_per_grp, + const WORD32 *ptr_sfb_offsets, WORD32 chn, FLOAT64 *ptr_ms_spec) { + FLOAT32 *ptr_sfb_enegry_left = pstr_psy_data[chn].ptr_sfb_energy_long; + FLOAT32 *ptr_sfb_energy_right = pstr_psy_data[chn + 1].ptr_sfb_energy_long; + const FLOAT32 *ptr_sfb_energy_mid = pstr_psy_data[chn].ptr_sfb_energy_long_ms; + const FLOAT32 *ptr_sfb_energy_side = pstr_psy_data[chn + 1].ptr_sfb_energy_long_ms; + FLOAT32 *ptr_sfb_thr_left = pstr_psy_data[chn].ptr_sfb_thr_long; + FLOAT32 *ptr_sfb_thr_right = pstr_psy_data[chn + 1].ptr_sfb_thr_long; + FLOAT32 *ptr_sfb_spread_energy_left = pstr_psy_data[chn].ptr_sfb_spreaded_energy_long; + FLOAT32 *ptr_sfb_spread_energy_right = pstr_psy_data[chn + 1].ptr_sfb_spreaded_energy_long; + WORD32 sfb, sfb_offsets, j; + WORD32 grp = 0; + WORD32 ms_counter = 0; + WORD32 lr_counter = 0; + + *ms_select = 0; + + for (sfb = 0; sfb < sfb_count; sfb += sfb_per_group, grp++) { + for (sfb_offsets = 0; sfb_offsets < max_sfb_per_grp; sfb_offsets++) { + FLOAT32 left_right, mid_side, min_thr; + WORD32 use_ms; + ms_used[grp][sfb_offsets] = 0; + + min_thr = MIN(ptr_sfb_thr_left[sfb + sfb_offsets], ptr_sfb_thr_right[sfb + sfb_offsets]); + + left_right = + (ptr_sfb_thr_left[sfb + sfb_offsets] / + MAX(ptr_sfb_enegry_left[sfb + sfb_offsets], ptr_sfb_thr_left[sfb + sfb_offsets])) * + (ptr_sfb_thr_right[sfb + sfb_offsets] / + max(ptr_sfb_energy_right[sfb + sfb_offsets], ptr_sfb_thr_right[sfb + sfb_offsets])); + + mid_side = (min_thr / max(ptr_sfb_energy_mid[sfb + sfb_offsets], min_thr)) * + (min_thr / max(ptr_sfb_energy_side[sfb + sfb_offsets], min_thr)); + + use_ms = (mid_side >= left_right); + + if (use_ms) { + ms_used[grp][sfb_offsets] = 1; + + for (j = ptr_sfb_offsets[sfb + sfb_offsets]; j < ptr_sfb_offsets[sfb + sfb_offsets + 1]; + j++) { + if (ptr_ms_spec != NULL) { + ptr_spec_left[j] = ptr_ms_spec[j]; + ptr_spec_right[j] = ptr_ms_spec[1024 + j]; + } else { + FLOAT64 tmp = ptr_spec_left[j]; + + ptr_spec_left[j] = 0.5f * (ptr_spec_left[j] + ptr_spec_right[j]); + + ptr_spec_right[j] = 0.5f * (tmp - ptr_spec_right[j]); + } + } + + ptr_sfb_thr_left[sfb + sfb_offsets] = ptr_sfb_thr_right[sfb + sfb_offsets] = min_thr; + + ptr_sfb_enegry_left[sfb + sfb_offsets] = ptr_sfb_energy_mid[sfb + sfb_offsets]; + ptr_sfb_energy_right[sfb + sfb_offsets] = ptr_sfb_energy_side[sfb + sfb_offsets]; + + ptr_sfb_spread_energy_left[sfb + sfb_offsets] = + ptr_sfb_spread_energy_right[sfb + sfb_offsets] = + min(ptr_sfb_spread_energy_left[sfb + sfb_offsets], + ptr_sfb_spread_energy_right[sfb + sfb_offsets]) * + 0.5f; + + ms_counter++; + } else { + ms_used[grp][sfb_offsets] = 0; + lr_counter++; + } + } + } + + if (ms_counter == 0) { + *ms_select = 0; + } else { + if (lr_counter != 0) { + *ms_select = 1; + } else { + *ms_select = 2; + } + } + return; +} + +VOID iusace_calc_ms_band_energy(const FLOAT64 *ptr_spec_left, const FLOAT64 *ptr_spec_right, + const WORD32 *ptr_band_offset, const WORD32 num_bands, + FLOAT32 *ptr_band_energy_mid, FLOAT32 *ptr_band_energy_side) { + WORD32 i, j; + + j = 0; + for (i = 0; i < num_bands; i++) { + ptr_band_energy_mid[i] = 0.0f; + ptr_band_energy_side[i] = 0.0f; + + while (j < ptr_band_offset[i + 1]) { + FLOAT32 specm, specs; + + specm = (FLOAT32)(0.5f * (ptr_spec_left[j] + ptr_spec_right[j])); + specs = (FLOAT32)(0.5f * (ptr_spec_left[j] - ptr_spec_right[j])); + + ptr_band_energy_mid[i] += specm * specm; + ptr_band_energy_side[i] += specs * specs; + + j++; + } + } + + return; +} diff --git a/encoder/iusace_ms.h b/encoder/iusace_ms.h new file mode 100644 index 0000000..f9de040 --- /dev/null +++ b/encoder/iusace_ms.h @@ -0,0 +1,35 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +typedef struct { + WORD32 ms_mask; + WORD32 ms_used[MAX_SHORT_WINDOWS][MAX_SFB_LONG]; +} ia_ms_info_struct; + +VOID iusace_ms_apply(ia_psy_mod_data_struct *pstr_psy_data, FLOAT64 *ptr_spec_left, + FLOAT64 *ptr_spec_right, WORD32 *ms_select, + WORD32 ms_used[MAX_SHORT_WINDOWS][MAX_SFB_LONG], const WORD32 sfb_count, + const WORD32 sfb_per_group, const WORD32 max_sfb_per_grp, + const WORD32 *ptr_sfb_offsets, WORD32 chn, FLOAT64 *ptr_ms_spec); + +VOID iusace_calc_ms_band_energy(const FLOAT64 *ptr_spec_left, const FLOAT64 *ptr_spec_right, + const WORD32 *ptr_band_offset, const WORD32 num_bands, + FLOAT32 *ptr_band_energy_mid, FLOAT32 *ptr_band_energy_side); diff --git a/encoder/iusace_psy_mod.c b/encoder/iusace_psy_mod.c new file mode 100644 index 0000000..ea737f1 --- /dev/null +++ b/encoder/iusace_psy_mod.c @@ -0,0 +1,275 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include "iusace_cnst.h" +#include "iusace_type_def.h" +#include "iusace_block_switch_const.h" +#include "iusace_block_switch_struct_def.h" +#include "iusace_bitbuffer.h" +#include "iusace_tns_usac.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_api.h" +#include "impd_drc_uni_drc_eq.h" +#include "impd_drc_uni_drc_filter_bank.h" +#include "impd_drc_gain_enc.h" +#include "impd_drc_struct_def.h" +#include "iusace_cnst.h" +#include "iusace_tns_usac.h" +#include "iusace_psy_mod.h" +#include "iusace_psy_utils.h" + +#include "ixheaac_error_standards.h" +#include "iusace_type_def.h" +#include "iusace_cnst.h" + +#include "iusace_ms.h" + +#include "iusace_psy_utils.h" +#include "ixheaace_adjust_threshold_data.h" +#include "iusace_fd_qc_util.h" +#include "ixheaace_memory_standards.h" +#include "iusace_config.h" +#include "iusace_arith_enc.h" +#include "iusace_fd_quant.h" +#include "iusace_signal_classifier.h" +#include "iusace_block_switch_const.h" +#include "ixheaace_sbr_header.h" +#include "ixheaace_config.h" +#include "ixheaace_asc_write.h" +#include "iusace_main.h" + +VOID iusace_psy_mod_init(ia_psy_mod_struct *pstr_psy_mod, WORD32 sample_rate, WORD32 bit_rate, + WORD32 band_width, WORD32 num_channels, WORD32 ch, WORD32 ele_id, + WORD32 ccfl) { + WORD32 i; + + for (i = 0; i < num_channels; i++) { + iusace_psy_long_config_init(bit_rate / num_channels, sample_rate, band_width, + &(pstr_psy_mod->str_psy_long_config[ele_id]), ccfl); + + iusace_psy_short_config_init(bit_rate / num_channels, sample_rate, band_width, + &(pstr_psy_mod->str_psy_short_config[ele_id]), ccfl); + + pstr_psy_mod->str_psy_data[ch].ptr_sfb_thr_long = + (FLOAT32 *)pstr_psy_mod->str_psy_data[ch].sfb_thr_short; + pstr_psy_mod->str_psy_data[ch].ptr_sfb_energy_long = + (FLOAT32 *)pstr_psy_mod->str_psy_data[ch].sfb_energy_short; + pstr_psy_mod->str_psy_data[ch].ptr_sfb_spreaded_energy_long = + (FLOAT32 *)pstr_psy_mod->str_psy_data[ch].sfb_spreaded_energy_short; + + memcpy(pstr_psy_mod->str_psy_data[ch].sfb_thr_nm1, + pstr_psy_mod->str_psy_long_config[ele_id].sfb_thr_quiet, + pstr_psy_mod->str_psy_long_config[ele_id].sfb_count * sizeof(FLOAT32)); + + ch++; + } + + return; +} + +VOID iusace_psy_mod_lb(ia_psy_mod_struct *pstr_psy_mod, ia_sfb_params_struct *pstr_sfb_prms, + FLOAT64 *ptr_spec_in, ia_tns_info *pstr_tns_info[MAX_TIME_CHANNELS], + WORD32 tns_select, WORD32 i_ch, WORD32 chn, WORD32 channel_type, + FLOAT64 *scratch_tns_filter, WORD32 elem_idx, FLOAT64 *ptr_tns_scratch, + WORD32 ccfl) { + ia_psy_mod_data_struct *pstr_psy_data = &(pstr_psy_mod->str_psy_data[i_ch]); + ia_psy_mod_long_config_struct *pstr_psy_config = &(pstr_psy_mod->str_psy_long_config[elem_idx]); + WORD32 window_sequence = pstr_sfb_prms->window_sequence[i_ch]; + WORD32 num_sfb = pstr_sfb_prms->num_sfb[i_ch]; + ia_tns_info *ptr_tns_info = pstr_tns_info[i_ch]; + WORD32 sfb, line; + WORD32 i; + WORD32 frame_len_long = ccfl; + FLOAT32 energy_shift = 0.25f; + FLOAT32 clip_energy = pstr_psy_config->clip_energy * energy_shift; + (VOID) channel_type; + + pstr_psy_data->window_sequence = window_sequence; + memset(&ptr_spec_in[pstr_psy_config->low_pass_line], 0, + (frame_len_long - pstr_psy_config->low_pass_line) * sizeof(FLOAT64)); + + iusace_calc_band_energy(ptr_spec_in, pstr_psy_config->sfb_offset, pstr_psy_config->sfb_active, + pstr_psy_data->ptr_sfb_energy_long, pstr_psy_config->sfb_count); + + if (tns_select != 0) { + ia_tns_info *ptr_tns_info_ch2 = pstr_tns_info[i_ch - chn]; + ptr_tns_info->number_of_bands = num_sfb; + ptr_tns_info->block_type = window_sequence; + ptr_tns_info->spec = ptr_spec_in; + iusace_tns_encode(ptr_tns_info_ch2, ptr_tns_info, pstr_psy_data->ptr_sfb_energy_long, 0, chn, + pstr_psy_config->low_pass_line, scratch_tns_filter, 0, ptr_tns_scratch); + } + + for (i = 0; i < pstr_psy_config->sfb_count; i++) { + pstr_psy_data->ptr_sfb_thr_long[i] = + pstr_psy_data->ptr_sfb_energy_long[i] * pstr_psy_config->ratio; + pstr_psy_data->ptr_sfb_thr_long[i] = MIN(pstr_psy_data->ptr_sfb_thr_long[i], clip_energy); + } + + if (tns_select != 0) { + if (ptr_tns_info->tns_data_present == 1) { + iusace_calc_band_energy(ptr_spec_in, pstr_psy_config->sfb_offset, + pstr_psy_config->sfb_active, pstr_psy_data->ptr_sfb_energy_long, + pstr_psy_config->sfb_count); + } + } + + iusace_find_max_spreading(pstr_psy_config->sfb_count, pstr_psy_config->sfb_mask_low_fac, + pstr_psy_config->sfb_mask_high_fac, pstr_psy_data->ptr_sfb_thr_long); + + for (i = 0; i < pstr_psy_config->sfb_count; i++) { + pstr_psy_data->ptr_sfb_thr_long[i] = MAX(pstr_psy_data->ptr_sfb_thr_long[i], + (pstr_psy_config->sfb_thr_quiet[i] * energy_shift)); + } + + if (pstr_psy_data->window_sequence == LONG_STOP_SEQUENCE) { + for (i = 0; i < pstr_psy_config->sfb_count; i++) { + pstr_psy_data->sfb_thr_nm1[i] = 1.0e20f; + } + } + + iusace_pre_echo_control(pstr_psy_data->sfb_thr_nm1, pstr_psy_config->sfb_count, + pstr_psy_config->max_allowed_inc_fac, + pstr_psy_config->min_remaining_thr_fac, + pstr_psy_data->ptr_sfb_thr_long); + + if (pstr_psy_data->window_sequence == LONG_START_SEQUENCE) { + for (i = 0; i < pstr_psy_config->sfb_count; i++) { + pstr_psy_data->sfb_thr_nm1[i] = 1.0e20f; + } + } + + for (i = 0; i < pstr_psy_config->sfb_count; i++) { + pstr_psy_data->ptr_sfb_spreaded_energy_long[i] = pstr_psy_data->ptr_sfb_energy_long[i]; + } + iusace_find_max_spreading( + pstr_psy_config->sfb_count, pstr_psy_config->sfb_mask_low_fac_spr_ener, + pstr_psy_config->sfb_mask_high_fac_spr_ener, pstr_psy_data->ptr_sfb_spreaded_energy_long); + + for (sfb = pstr_psy_config->sfb_count - 1; sfb >= 0; sfb--) { + for (line = pstr_psy_config->sfb_offset[sfb + 1] - 1; + line >= pstr_psy_config->sfb_offset[sfb]; line--) { + if (ptr_spec_in[line] != 0) break; + } + if (line >= pstr_psy_config->sfb_offset[sfb]) break; + } + + pstr_psy_mod->str_psy_out_data[i_ch].max_sfb_per_grp = sfb + 1; + + return; +} + +VOID iusace_psy_mod_sb(ia_psy_mod_struct *pstr_psy_mod, ia_sfb_params_struct *pstr_sfb_prms, + FLOAT64 *ptr_spec_in, ia_tns_info *pstr_tns_info[MAX_TIME_CHANNELS], + WORD32 tns_select, WORD32 i_ch, WORD32 chn, WORD32 channel_type, + FLOAT64 *scratch_tns_filter, WORD32 elem_idx, FLOAT64 *ptr_tns_scratch, + WORD32 ccfl) { + ia_psy_mod_data_struct *pstr_psy_data = &(pstr_psy_mod->str_psy_data[i_ch]); + ia_psy_mod_short_config_struct *pstr_psy_config = + &(pstr_psy_mod->str_psy_short_config[elem_idx]); + WORD32 max_sfb = 0, sfb, line; + WORD32 window_sequence = pstr_sfb_prms->window_sequence[i_ch]; + WORD32 num_sfb = pstr_sfb_prms->num_sfb[i_ch]; + ia_tns_info *ptr_tns_info = pstr_tns_info[i_ch]; + WORD32 i, w; + WORD32 frame_len_short = (ccfl * FRAME_LEN_SHORT_128) / FRAME_LEN_LONG; + FLOAT32 energy_shift = 0.25f; + FLOAT32 clip_energy = pstr_psy_config->clip_energy * energy_shift; + (VOID) channel_type; + + pstr_psy_data->window_sequence = window_sequence; + + for (w = 0; w < MAX_SHORT_WINDOWS; w++) { + WORD32 w_offset = w * frame_len_short; + WORD32 offset; + FLOAT64 *pmdct_double = &ptr_spec_in[pstr_psy_config->low_pass_line + w_offset]; + + offset = frame_len_short - pstr_psy_config->low_pass_line; + + memset(pmdct_double, 0, sizeof(FLOAT64) * offset); + + iusace_calc_band_energy(ptr_spec_in + w_offset, pstr_psy_config->sfb_offset, + pstr_psy_config->sfb_active, pstr_psy_data->sfb_energy_short[w], + pstr_psy_config->sfb_count); + + if (tns_select != 0) { + ia_tns_info *ptr_tns_info_ch2 = pstr_tns_info[i_ch - chn]; + ptr_tns_info->number_of_bands = num_sfb; + ptr_tns_info->block_type = window_sequence; + ptr_tns_info->spec = ptr_spec_in + w_offset; + iusace_tns_encode(ptr_tns_info_ch2, ptr_tns_info, pstr_psy_data->sfb_energy_short[w], w, + chn, pstr_psy_config->low_pass_line, scratch_tns_filter, 0, + ptr_tns_scratch); + } + + for (i = 0; i < pstr_psy_config->sfb_count; i++) { + pstr_psy_data->sfb_thr_short[w][i] = + pstr_psy_data->sfb_energy_short[w][i] * pstr_psy_config->ratio; + pstr_psy_data->sfb_thr_short[w][i] = MIN(pstr_psy_data->sfb_thr_short[w][i], clip_energy); + } + + if (tns_select != 0) { + if (ptr_tns_info->tns_data_present == 1) { + iusace_calc_band_energy(ptr_spec_in + w_offset, pstr_psy_config->sfb_offset, + pstr_psy_config->sfb_active, pstr_psy_data->sfb_energy_short[w], + pstr_psy_config->sfb_count); + } + } + + iusace_find_max_spreading(pstr_psy_config->sfb_count, pstr_psy_config->sfb_mask_low_fac, + pstr_psy_config->sfb_mask_high_fac, + pstr_psy_data->sfb_thr_short[w]); + + for (i = 0; i < pstr_psy_config->sfb_count; i++) { + pstr_psy_data->sfb_thr_short[w][i] = + MAX(pstr_psy_data->sfb_thr_short[w][i], (pstr_psy_config->sfb_thr_quiet[i] * 0.25f)); + } + + iusace_pre_echo_control(pstr_psy_data->sfb_thr_nm1, pstr_psy_config->sfb_count, + pstr_psy_config->max_allowed_inc_fac, + pstr_psy_config->min_remaining_thr_fac, + pstr_psy_data->sfb_thr_short[w]); + + for (i = 0; i < pstr_psy_config->sfb_count; i++) { + pstr_psy_data->sfb_spreaded_energy_short[w][i] = pstr_psy_data->sfb_energy_short[w][i]; + } + iusace_find_max_spreading( + pstr_psy_config->sfb_count, pstr_psy_config->sfb_mask_low_fac_spr_ener, + pstr_psy_config->sfb_mask_high_fac_spr_ener, pstr_psy_data->sfb_spreaded_energy_short[w]); + } + + for (WORD32 wnd = 0; wnd < MAX_SHORT_WINDOWS; wnd++) { + for (sfb = pstr_psy_config->sfb_count - 1; sfb >= max_sfb; sfb--) { + for (line = pstr_psy_config->sfb_offset[sfb + 1] - 1; + line >= pstr_psy_config->sfb_offset[sfb]; line--) { + if (ptr_spec_in[wnd * frame_len_short + line] != 0.0) break; + } + if (line >= pstr_psy_config->sfb_offset[sfb]) break; + } + max_sfb = MAX(max_sfb, sfb); + } + max_sfb = max_sfb > 0 ? max_sfb : 0; + + pstr_psy_mod->str_psy_out_data[i_ch].max_sfb_per_grp = max_sfb + 1; + + return; +} diff --git a/encoder/iusace_psy_mod.h b/encoder/iusace_psy_mod.h new file mode 100644 index 0000000..b051d2f --- /dev/null +++ b/encoder/iusace_psy_mod.h @@ -0,0 +1,150 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +#include + +#define MAX_NUM_GROUPED_SFB (60) +#define MAX_BARK_VALUE (24.0f) +#define MASK_LOW_FAC (3.0f) +#define MASK_HIGH_FAC (1.5f) +#define MASK_LOW_SP_ENERGY_L (3.0f) +#define MASK_HIGH_SP_ENERGY_L (2.0f) +#define MASK_HIGH_SP_ENERGY_L_LBR (1.5f) +#define MASK_LOW_SP_ENERGY_S (2.0f) +#define MASK_HIGH_SP_ENERGY_S (1.5f) +#define C_RATIO (0.001258925f) + +#define MAXIMUM_SCALE_FACTOR_BAND_LONG 51 +#define MAXIMUM_SCALE_FACTOR_BAND_SHORT 15 + +#define MAX_GROUPED_SFB 51 +#define MAX_GROUPED_SFB_TEMP 60 +#define BLOCK_SWITCHING_OFFSET (1 * 1024 + 3 * 128 + 64 + 128) +#define MAX_CHANNEL_BITS 6144 +#define MAX_SFB_SHORT 15 + +#define TRANS_FAC 8 +#ifndef FRAME_LEN_SHORT_128 +#define FRAME_LEN_SHORT_128 (FRAME_LEN_LONG / TRANS_FAC) +#endif + +typedef struct { + WORD32 sfb_count; + WORD32 sfb_active; + WORD32 sfb_offset[MAXIMUM_SCALE_FACTOR_BAND_LONG + 1]; + FLOAT32 sfb_thr_quiet[MAXIMUM_SCALE_FACTOR_BAND_LONG]; + FLOAT32 max_allowed_inc_fac; + FLOAT32 min_remaining_thr_fac; + WORD32 low_pass_line; + FLOAT32 clip_energy; + FLOAT32 ratio; + FLOAT32 sfb_mask_low_fac[MAXIMUM_SCALE_FACTOR_BAND_LONG]; + FLOAT32 sfb_mask_high_fac[MAXIMUM_SCALE_FACTOR_BAND_LONG]; + FLOAT32 sfb_mask_low_fac_spr_ener[MAXIMUM_SCALE_FACTOR_BAND_LONG]; + FLOAT32 sfb_mask_high_fac_spr_ener[MAXIMUM_SCALE_FACTOR_BAND_LONG]; + FLOAT32 sfb_min_snr[MAXIMUM_SCALE_FACTOR_BAND_LONG]; +} ia_psy_mod_long_config_struct; + +typedef struct { + WORD32 sfb_count; + WORD32 sfb_active; + WORD32 sfb_offset[MAXIMUM_SCALE_FACTOR_BAND_SHORT + 1]; + FLOAT32 sfb_thr_quiet[MAXIMUM_SCALE_FACTOR_BAND_SHORT]; + FLOAT32 max_allowed_inc_fac; + FLOAT32 min_remaining_thr_fac; + WORD32 low_pass_line; + FLOAT32 clip_energy; + FLOAT32 ratio; + FLOAT32 sfb_mask_low_fac[MAXIMUM_SCALE_FACTOR_BAND_SHORT]; + FLOAT32 sfb_mask_high_fac[MAXIMUM_SCALE_FACTOR_BAND_SHORT]; + FLOAT32 sfb_mask_low_fac_spr_ener[MAXIMUM_SCALE_FACTOR_BAND_SHORT]; + FLOAT32 sfb_mask_high_fac_spr_ener[MAXIMUM_SCALE_FACTOR_BAND_SHORT]; + FLOAT32 sfb_min_snr[MAXIMUM_SCALE_FACTOR_BAND_SHORT]; +} ia_psy_mod_short_config_struct; + +typedef struct { + WORD32 sfb_count; + WORD32 max_sfb_per_grp; + WORD32 sfb_per_group; + WORD32 window_sequence; + WORD32 window_shape; + WORD32 sfb_offsets[100]; + FLOAT32 *ptr_sfb_energy; + FLOAT32 *ptr_sfb_spread_energy; + FLOAT32 *ptr_sfb_thr; + FLOAT64 *ptr_spec_coeffs; + FLOAT32 sfb_sum_lr_energy; + FLOAT32 pe; + FLOAT32 sfb_min_snr[100]; + WORD32 ms_used[100]; +} ia_psy_mod_out_data_struct; + +typedef struct { + WORD32 window_sequence; + FLOAT32 sfb_thr_nm1[MAX_GROUPED_SFB_TEMP]; + FLOAT32 *ptr_sfb_thr_long; + FLOAT32 sfb_thr_short[TRANS_FAC][MAXIMUM_SCALE_FACTOR_BAND_SHORT]; + FLOAT32 *ptr_sfb_energy_long; + FLOAT32 ptr_sfb_energy_long_ms[MAX_GROUPED_SFB_TEMP]; + FLOAT32 ptr_sfb_energy_short_ms[TRANS_FAC][MAXIMUM_SCALE_FACTOR_BAND_SHORT]; + FLOAT32 sfb_energy_short[TRANS_FAC][MAXIMUM_SCALE_FACTOR_BAND_SHORT]; + FLOAT32 *ptr_sfb_spreaded_energy_long; + FLOAT32 sfb_spreaded_energy_short[TRANS_FAC][MAXIMUM_SCALE_FACTOR_BAND_SHORT]; +} ia_psy_mod_data_struct; + +typedef struct ia_psy_mod_struct { + ia_psy_mod_long_config_struct str_psy_long_config[MAX_TIME_CHANNELS]; + ia_psy_mod_short_config_struct str_psy_short_config[MAX_TIME_CHANNELS]; + ia_psy_mod_data_struct str_psy_data[MAX_TIME_CHANNELS]; + ia_psy_mod_out_data_struct str_psy_out_data[MAX_TIME_CHANNELS]; + FLOAT32 mdct_spec_coeff_buf[MAX_TIME_CHANNELS][1024]; +} ia_psy_mod_struct; + +typedef struct ia_sfb_params_struct { + WORD32 num_sfb[MAX_TIME_CHANNELS]; + WORD32 max_sfb[MAX_TIME_CHANNELS]; + WORD32 max_sfb_ste; + WORD32 sfb_width_table[MAX_TIME_CHANNELS][MAX_SFB_LONG]; + WORD32 grouped_sfb_offset[MAX_TIME_CHANNELS][MAX_SF_BANDS + 1]; + WORD32 sfb_offset[MAX_TIME_CHANNELS][MAX_SF_BANDS + 1]; + WORD32 num_window_groups[MAX_TIME_CHANNELS]; + WORD32 window_group_length[MAX_TIME_CHANNELS][8]; + WORD32 window_shape[MAX_TIME_CHANNELS]; + WORD32 window_sequence[MAX_TIME_CHANNELS]; + WORD32 common_win[MAX_TIME_CHANNELS]; + +} ia_sfb_params_struct; + +VOID iusace_psy_mod_init(ia_psy_mod_struct *pstr_psy_mod, WORD32 sample_rate, WORD32 bit_rate, + WORD32 band_width, WORD32 num_channels, WORD32 ch, WORD32 ele_id, + WORD32 ccfl); + +VOID iusace_psy_mod_sb(ia_psy_mod_struct *pstr_psy_mod, ia_sfb_params_struct *pstr_sfb_prms, + FLOAT64 *ptr_spec_in, ia_tns_info *pstr_tns_info[MAX_TIME_CHANNELS], + WORD32 tns_select, WORD32 i_ch, WORD32 chn, WORD32 channel_type, + FLOAT64 *scratch_tns_filter, WORD32 elem_idx, FLOAT64 *ptr_tns_scratch, + WORD32 ccfl); + +VOID iusace_psy_mod_lb(ia_psy_mod_struct *pstr_psy_mod, ia_sfb_params_struct *pstr_sfb_prms, + FLOAT64 *ptr_spec_in, ia_tns_info *pstr_tns_info[MAX_TIME_CHANNELS], + WORD32 tns_select, WORD32 i_ch, WORD32 chn, WORD32 channel_type, + FLOAT64 *scratch_tns_filter, WORD32 elem_idx, FLOAT64 *ptr_tns_scratch, + WORD32 ccfl); diff --git a/encoder/iusace_psy_rom.c b/encoder/iusace_psy_rom.c new file mode 100644 index 0000000..0d627dd --- /dev/null +++ b/encoder/iusace_psy_rom.c @@ -0,0 +1,218 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include "iusace_type_def.h" +#include "iusace_cnst.h" +#include "iusace_tns_usac.h" +#include "iusace_psy_mod.h" +#include "iusace_psy_utils.h" + +const WORD16 iusace_sfb_96_1024[] = {4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, + 48, 52, 56, 64, 72, 80, 88, 96, 108, 120, 132, + 144, 156, 172, 188, 212, 240, 276, 320, 384, 448, 512, + 576, 640, 704, 768, 832, 896, 960, 1024}; + +const WORD16 iexheaac_sfb_96_768[] = { + 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 64, 72, 80, 88, 96, + 108, 120, 132, 144, 156, 172, 188, 212, 240, 276, 320, 384, 448, 512, 576, 640, 704, 768}; + +const WORD16 iusace_sfb_96_128[] = {4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92, 128}; + +const WORD16 iexheaac_sfb_96_96[] = {4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92, 96}; + +const WORD16 iusace_sfb_64_1024[] = {4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, + 52, 56, 64, 72, 80, 88, 100, 112, 124, 140, 156, 172, + 192, 216, 240, 268, 304, 344, 384, 424, 464, 504, 544, 584, + 624, 664, 704, 744, 784, 824, 864, 904, 944, 984, 1024}; + +const WORD16 iusace_sfb_64_768[] = {4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, + 48, 52, 56, 64, 72, 80, 88, 100, 112, 124, 140, + 156, 172, 192, 216, 240, 268, 304, 344, 384, 424, 464, + 504, 544, 584, 624, 664, 704, 744, 768}; + +const WORD16 iusace_sfb_64_128[] = {4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92, 128}; + +const WORD16 iusace_sfb_64_96[] = {4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92, 96}; + +const WORD16 iusace_sfb_48_1024[] = { + 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 48, 56, 64, 72, 80, 88, 96, + 108, 120, 132, 144, 160, 176, 196, 216, 240, 264, 292, 320, 352, 384, 416, 448, 480, + 512, 544, 576, 608, 640, 672, 704, 736, 768, 800, 832, 864, 896, 928, 1024}; + +const WORD16 iexheaac_sfb_48_768[] = {4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 48, + 56, 64, 72, 80, 88, 96, 108, 120, 132, 144, 160, + 176, 196, 216, 240, 264, 292, 320, 352, 384, 416, 448, + 480, 512, 544, 576, 608, 640, 672, 704, 736, 768}; + +const WORD16 iusace_sfb_48_128[] = {4, 8, 12, 16, 20, 28, 36, 44, 56, 68, 80, 96, 112, 128}; + +const WORD16 iexheaac_sfb_48_96[] = {4, 8, 12, 16, 20, 28, 36, 44, 56, 68, 80, 96}; + +const WORD16 iusace_sfb_32_1024[] = { + 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 48, 56, 64, 72, 80, 88, 96, + 108, 120, 132, 144, 160, 176, 196, 216, 240, 264, 292, 320, 352, 384, 416, 448, 480, + 512, 544, 576, 608, 640, 672, 704, 736, 768, 800, 832, 864, 896, 928, 960, 992, 1024}; + +const WORD16 iexheaac_sfb_32_768[] = {4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 48, + 56, 64, 72, 80, 88, 96, 108, 120, 132, 144, 160, + 176, 196, 216, 240, 264, 292, 320, 352, 384, 416, 448, + 480, 512, 544, 576, 608, 640, 672, 704, 736, 768}; + +const WORD16 iusace_sfb_24_1024[] = {4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 52, + 60, 68, 76, 84, 92, 100, 108, 116, 124, 136, 148, 160, + 172, 188, 204, 220, 240, 260, 284, 308, 336, 364, 396, 432, + 468, 508, 552, 600, 652, 704, 768, 832, 896, 960, 1024}; + +const WORD16 iexheaac_sfb_24_768[] = {4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, + 52, 60, 68, 76, 84, 92, 100, 108, 116, 124, 136, + 148, 160, 172, 188, 204, 220, 240, 260, 284, 308, 336, + 364, 396, 432, 468, 508, 552, 600, 652, 704, 768}; + +const WORD16 iusace_sfb_24_128[] = {4, 8, 12, 16, 20, 24, 28, 36, 44, 52, 64, 76, 92, 108, 128}; + +const WORD16 iexheaac_sfb_24_96[] = {4, 8, 12, 16, 20, 24, 28, 36, 44, 52, 64, 76, 92, 96}; + +const WORD16 iusace_sfb_16_1024[] = {8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, + 100, 112, 124, 136, 148, 160, 172, 184, 196, 212, 228, + 244, 260, 280, 300, 320, 344, 368, 396, 424, 456, 492, + 532, 572, 616, 664, 716, 772, 832, 896, 960, 1024}; + +const WORD16 iexheaac_sfb_16_768[] = {8, 16, 24, 32, 40, 48, 56, 64, 72, 80, + 88, 100, 112, 124, 136, 148, 160, 172, 184, 196, + 212, 228, 244, 260, 280, 300, 320, 344, 368, 396, + 424, 456, 492, 532, 572, 616, 664, 716, 768}; + +const WORD16 iusace_sfb_16_128[] = {4, 8, 12, 16, 20, 24, 28, 32, 40, 48, 60, 72, 88, 108, 128}; + +const WORD16 iexheaac_sfb_16_96[] = {4, 8, 12, 16, 20, 24, 28, 32, 40, 48, 60, 72, 88, 96}; + +const WORD16 iusace_sfb_8_1024[] = {12, 24, 36, 48, 60, 72, 84, 96, 108, 120, + 132, 144, 156, 172, 188, 204, 220, 236, 252, 268, + 288, 308, 328, 348, 372, 396, 420, 448, 476, 508, + 544, 580, 620, 664, 712, 764, 820, 880, 944, 1024}; + +const WORD16 iusace_sfb_8_128[] = {4, 8, 12, 16, 20, 24, 28, 36, 44, 52, 60, 72, 88, 108, 128}; + +const WORD16 iusace_sfb_8_768[] = { + 12, 24, 36, 48, 60, 72, 84, 96, 108, 120, 132, 144, 156, 172, 188, 204, 220, 236, 252, + 268, 288, 308, 328, 348, 372, 396, 420, 448, 476, 508, 544, 580, 620, 664, 712, 764, 768}; + +const WORD16 iusace_sfb_8_96[] = {4, 8, 12, 16, 20, 24, 28, 36, 44, 52, 60, 72, 88, 96}; + +ia_sfb_info_struct iusace_sfb_info_1024[12] = { + {8000, 40, 15, iusace_sfb_8_1024, iusace_sfb_8_128, {0}, {0}}, + {11025, 43, 15, iusace_sfb_16_1024, iusace_sfb_16_128, {0}, {0}}, + {12000, 43, 15, iusace_sfb_16_1024, iusace_sfb_16_128, {0}, {0}}, + {16000, 43, 15, iusace_sfb_16_1024, iusace_sfb_16_128, {0}, {0}}, + {22050, 47, 15, iusace_sfb_24_1024, iusace_sfb_24_128, {0}, {0}}, + {24000, 47, 15, iusace_sfb_24_1024, iusace_sfb_24_128, {0}, {0}}, + {32000, 51, 14, iusace_sfb_32_1024, iusace_sfb_48_128, {0}, {0}}, + {44100, 49, 14, iusace_sfb_48_1024, iusace_sfb_48_128, {0}, {0}}, + {48000, 49, 14, iusace_sfb_48_1024, iusace_sfb_48_128, {0}, {0}}, + {64000, 47, 12, iusace_sfb_64_1024, iusace_sfb_64_128, {0}, {0}}, + {88200, 41, 12, iusace_sfb_64_1024, iusace_sfb_64_128, {0}, {0}}, + {96000, 41, 12, iusace_sfb_96_1024, iusace_sfb_96_128, {0}, {0}}}; + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) + +ia_sfb_info_struct iusace_sfb_info_768[12] = {{8000, + ARRAY_SIZE(iusace_sfb_8_768), + ARRAY_SIZE(iusace_sfb_8_96), + iusace_sfb_8_768, + iusace_sfb_8_96, + {0}, + {0}}, + {11025, + ARRAY_SIZE(iexheaac_sfb_16_768), + ARRAY_SIZE(iexheaac_sfb_16_96), + iexheaac_sfb_16_768, + iexheaac_sfb_16_96, + {0}, + {0}}, + {12000, + ARRAY_SIZE(iexheaac_sfb_16_768), + ARRAY_SIZE(iexheaac_sfb_16_96), + iexheaac_sfb_16_768, + iexheaac_sfb_16_96, + {0}, + {0}}, + {16000, + ARRAY_SIZE(iexheaac_sfb_16_768), + ARRAY_SIZE(iexheaac_sfb_16_96), + iexheaac_sfb_16_768, + iexheaac_sfb_16_96, + {0}, + {0}}, + {22050, + ARRAY_SIZE(iexheaac_sfb_24_768), + ARRAY_SIZE(iexheaac_sfb_24_96), + iexheaac_sfb_24_768, + iexheaac_sfb_24_96, + {0}, + {0}}, + {24000, + ARRAY_SIZE(iexheaac_sfb_24_768), + ARRAY_SIZE(iexheaac_sfb_24_96), + iexheaac_sfb_24_768, + iexheaac_sfb_24_96, + {0}, + {0}}, + {32000, + ARRAY_SIZE(iexheaac_sfb_48_768), + ARRAY_SIZE(iexheaac_sfb_48_96), + iexheaac_sfb_48_768, + iexheaac_sfb_48_96, + {0}, + {0}}, + {44100, + ARRAY_SIZE(iexheaac_sfb_48_768), + ARRAY_SIZE(iexheaac_sfb_48_96), + iexheaac_sfb_48_768, + iexheaac_sfb_48_96, + {0}, + {0}}, + {48000, + ARRAY_SIZE(iexheaac_sfb_48_768), + ARRAY_SIZE(iexheaac_sfb_48_96), + iexheaac_sfb_48_768, + iexheaac_sfb_48_96, + {0}, + {0}}, + {64000, + ARRAY_SIZE(iusace_sfb_64_768), + ARRAY_SIZE(iusace_sfb_64_96), + iusace_sfb_64_768, + iusace_sfb_64_96, + {0}, + {0}}, + {88200, + ARRAY_SIZE(iusace_sfb_64_768), + ARRAY_SIZE(iusace_sfb_64_96), + iusace_sfb_64_768, + iusace_sfb_64_96, + {0}, + {0}}, + {96000, + ARRAY_SIZE(iexheaac_sfb_96_768), + ARRAY_SIZE(iexheaac_sfb_96_96), + iexheaac_sfb_96_768, + iexheaac_sfb_96_96, + {0}, + {0}}}; diff --git a/encoder/iusace_psy_utils.c b/encoder/iusace_psy_utils.c new file mode 100644 index 0000000..bb03c15 --- /dev/null +++ b/encoder/iusace_psy_utils.c @@ -0,0 +1,550 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include + +#include "ixheaac_type_def.h" +#include "ixheaace_adjust_threshold_data.h" +#include "iusace_block_switch_const.h" +#include "iusace_cnst.h" +#include "iusace_bitbuffer.h" +#include "ixheaace_mps_common_define.h" + +/* DRC */ +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" +#include "impd_drc_uni_drc_eq.h" +#include "impd_drc_uni_drc_filter_bank.h" +#include "impd_drc_gain_enc.h" +#include "impd_drc_struct_def.h" + +#include "iusace_tns_usac.h" +#include "iusace_psy_mod.h" +#include "iusace_tns_usac.h" +#include "iusace_config.h" +#include "iusace_psy_utils.h" +#include "iusace_fd_qc_util.h" +#include "iusace_fd_qc_adjthr.h" + +extern ia_sfb_info_struct iusace_sfb_info_1024[12]; +extern ia_sfb_info_struct iusace_sfb_info_768[12]; + +static const FLOAT32 iusace_bark_quiet_thr_val[] = { + 15.0f, 10.0f, 7.0f, 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 3.0f, 5.0f, 10.0f, 20.0f, 30.0f}; + +VOID iusace_calc_band_energy(const FLOAT64 *ptr_spec_coeffs, const WORD32 *band_offset, + const WORD32 num_bands, FLOAT32 *ptr_band_energy, WORD32 sfb_count) { + WORD32 i, j; + + j = 0; + memset(ptr_band_energy, 0, sfb_count * sizeof(FLOAT32)); + for (i = 0; i < num_bands; i++) { + while (j < band_offset[i + 1]) { + ptr_band_energy[i] += (FLOAT32)(ptr_spec_coeffs[j] * ptr_spec_coeffs[j]); + j++; + } + } + return; +} + +VOID iusace_find_max_spreading(const WORD32 sfb_count, const FLOAT32 *ptr_mask_low_fac, + const FLOAT32 *ptr_mask_high_fac, FLOAT32 *ptr_spreaded_enegry) { + WORD32 i; + + for (i = 1; i < sfb_count; i++) { + ptr_spreaded_enegry[i] = + MAX(ptr_spreaded_enegry[i], ptr_mask_high_fac[i] * ptr_spreaded_enegry[i - 1]); + } + + for (i = sfb_count - 2; i >= 0; i--) { + ptr_spreaded_enegry[i] = + MAX(ptr_spreaded_enegry[i], ptr_mask_low_fac[i] * ptr_spreaded_enegry[i + 1]); + } + return; +} + +VOID iusace_pre_echo_control(FLOAT32 *ptr_thr_nm1, WORD32 sfb_count, FLOAT32 max_allowed_inc_fac, + FLOAT32 min_remaining_thr_fac, FLOAT32 *ptr_threshold) { + WORD32 i; + FLOAT32 thr1, thr2; + + for (i = 0; i < sfb_count; i++) { + thr1 = max_allowed_inc_fac * (ptr_thr_nm1[i]); + thr2 = min_remaining_thr_fac * ptr_threshold[i]; + + ptr_thr_nm1[i] = ptr_threshold[i]; + + if (ptr_threshold[i] > thr1) { + ptr_threshold[i] = thr1; + } + if (thr2 > ptr_threshold[i]) { + ptr_threshold[i] = thr2; + } + } + return; +} + +static VOID iusace_sfb_init(WORD32 sample_rate, WORD32 block_type, WORD32 *ptr_sfb_offset, + WORD32 *ptr_sfb_count, WORD32 ccfl) { + const WORD16 *ptr_sfb_params = 0; + WORD32 start_offset, block_len = 0; + const ia_sfb_info_struct *pstr_sfb_info_tbls = &iusace_sfb_info_1024[0]; + WORD32 sampling_rate_mapped = sample_rate; + WORD16 prev_val = 0; + if (ccfl == LEN_SUPERFRAME_768) { + pstr_sfb_info_tbls = &iusace_sfb_info_768[0]; + } + + if ((sample_rate >= 0) && (sample_rate < 9391)) { + sampling_rate_mapped = 8000; + } else if ((sample_rate >= 9391) && (sample_rate < 11502)) { + sampling_rate_mapped = 11025; + } else if ((sample_rate >= 11502) && (sample_rate < 13856)) { + sampling_rate_mapped = 12000; + } else if ((sample_rate >= 13856) && (sample_rate < 18783)) { + sampling_rate_mapped = 16000; + } else if ((sample_rate >= 18783) && (sample_rate < 23004)) { + sampling_rate_mapped = 22050; + } else if ((sample_rate >= 23004) && (sample_rate < 27713)) { + sampling_rate_mapped = 24000; + } else if ((sample_rate >= 27713) && (sample_rate < 37566)) { + sampling_rate_mapped = 32000; + } else if ((sample_rate >= 37566) && (sample_rate < 46009)) { + sampling_rate_mapped = 44100; + } else if ((sample_rate >= 46009) && (sample_rate < 55426)) { + sampling_rate_mapped = 48000; + } else if ((sample_rate >= 55426) && (sample_rate < 75132)) { + sampling_rate_mapped = 64000; + } else if ((sample_rate >= 75132) && (sample_rate < 92017)) { + sampling_rate_mapped = 88200; + } else if (sample_rate >= 92017) { + sampling_rate_mapped = 96000; + } else { + sampling_rate_mapped = 48000; + } + + if (block_type == ONLY_LONG_SEQUENCE) { + block_len = ccfl; + switch (sampling_rate_mapped) { + case 96000: + ptr_sfb_params = pstr_sfb_info_tbls[11].cb_offset_long; + break; + case 88200: + ptr_sfb_params = pstr_sfb_info_tbls[10].cb_offset_long; + break; + case 64000: + ptr_sfb_params = pstr_sfb_info_tbls[9].cb_offset_long; + break; + case 48000: + ptr_sfb_params = pstr_sfb_info_tbls[8].cb_offset_long; + break; + case 44100: + ptr_sfb_params = pstr_sfb_info_tbls[7].cb_offset_long; + break; + case 32000: + case 29400: + ptr_sfb_params = pstr_sfb_info_tbls[6].cb_offset_long; + break; + case 24000: + ptr_sfb_params = pstr_sfb_info_tbls[5].cb_offset_long; + break; + case 22050: + ptr_sfb_params = pstr_sfb_info_tbls[4].cb_offset_long; + break; + case 16000: + case 14700: + ptr_sfb_params = pstr_sfb_info_tbls[3].cb_offset_long; + break; + case 12000: + ptr_sfb_params = pstr_sfb_info_tbls[2].cb_offset_long; + break; + case 11025: + ptr_sfb_params = pstr_sfb_info_tbls[1].cb_offset_long; + break; + case 8000: + ptr_sfb_params = pstr_sfb_info_tbls[0].cb_offset_long; + break; + } + } else { + block_len = ccfl >> 3; + switch (sampling_rate_mapped) { + case 96000: + ptr_sfb_params = pstr_sfb_info_tbls[11].cb_offset_short; + break; + case 88200: + ptr_sfb_params = pstr_sfb_info_tbls[10].cb_offset_short; + break; + case 64000: + ptr_sfb_params = pstr_sfb_info_tbls[9].cb_offset_short; + break; + case 48000: + ptr_sfb_params = pstr_sfb_info_tbls[8].cb_offset_short; + break; + case 44100: + ptr_sfb_params = pstr_sfb_info_tbls[7].cb_offset_short; + break; + case 32000: + case 29400: + ptr_sfb_params = pstr_sfb_info_tbls[6].cb_offset_short; + break; + case 24000: + ptr_sfb_params = pstr_sfb_info_tbls[5].cb_offset_short; + break; + case 22050: + ptr_sfb_params = pstr_sfb_info_tbls[4].cb_offset_short; + break; + case 16000: + case 14700: + ptr_sfb_params = pstr_sfb_info_tbls[3].cb_offset_short; + break; + case 12000: + ptr_sfb_params = pstr_sfb_info_tbls[2].cb_offset_short; + break; + case 11025: + ptr_sfb_params = pstr_sfb_info_tbls[1].cb_offset_short; + break; + case 8000: + ptr_sfb_params = pstr_sfb_info_tbls[0].cb_offset_short; + break; + } + } + + *ptr_sfb_count = 0; + start_offset = 0; + + do { + ptr_sfb_offset[*ptr_sfb_count] = start_offset; + if (*ptr_sfb_count == 0) + prev_val = 0; + else + prev_val = ptr_sfb_params[*ptr_sfb_count - 1]; + start_offset += ptr_sfb_params[*ptr_sfb_count] - prev_val; + (*ptr_sfb_count)++; + } while (start_offset < block_len); + + ptr_sfb_offset[*ptr_sfb_count] = start_offset; + + return; +} + +static FLOAT32 iusace_atan_approx(FLOAT32 val) { + if (val < (FLOAT32)1.0) { + return (val / ((FLOAT32)1.0f + (FLOAT32)0.280872f * val * val)); + } else { + return ((FLOAT32)1.57079633f - val / ((FLOAT32)0.280872f + val * val)); + } +} + +static FLOAT32 iusace_calc_bark_line_value(WORD32 num_lines, WORD32 fft_line, + WORD32 sample_rate) { + FLOAT32 center_freq, temp, b_value; + + center_freq = (FLOAT32)fft_line * ((FLOAT32)sample_rate * (FLOAT32)0.5f) / (FLOAT32)num_lines; + temp = (FLOAT32)iusace_atan_approx((FLOAT32)1.3333333e-4f * center_freq); + b_value = (FLOAT32)13.3f * iusace_atan_approx((FLOAT32)0.00076f * center_freq) + + (FLOAT32)3.5f * temp * temp; + + return (b_value); +} + +static VOID iusace_bark_values_init(WORD32 sfb_count, WORD32 *ptr_sfb_offset, WORD32 num_lines, + WORD32 sample_rate, FLOAT32 *ptr_b_value) { + WORD32 i; + FLOAT32 b_val0, b_val1; + b_val0 = 0.0f; + + for (i = 0; i < sfb_count; i++) { + b_val1 = iusace_calc_bark_line_value(num_lines, ptr_sfb_offset[i + 1], sample_rate); + ptr_b_value[i] = (b_val0 + b_val1) * (FLOAT32)0.5f; + b_val0 = b_val1; + } + return; +} + +static VOID iusace_thr_quiet_init(WORD32 sfb_count, WORD32 *ptr_sfb_offset, FLOAT32 *ptr_bark_val, + FLOAT32 *ptr_thr_quiet) { + WORD32 i; + FLOAT32 bark_thr_quiet; + + for (i = 0; i < sfb_count; i++) { + WORD32 b_val1, b_val2; + + if (i > 0) { + b_val1 = (WORD32)(ptr_bark_val[i] + ptr_bark_val[i - 1]) >> 1; + } else { + b_val1 = (WORD32)(ptr_bark_val[i]) >> 1; + } + + if (i < sfb_count - 1) { + b_val2 = (WORD32)(ptr_bark_val[i] + ptr_bark_val[i + 1]) >> 1; + } else { + b_val2 = (WORD32)(ptr_bark_val[i]); + } + b_val1 = MIN(b_val1, (WORD32)MAX_BARK_VALUE); + b_val2 = MIN(b_val2, (WORD32)MAX_BARK_VALUE); + bark_thr_quiet = MIN(iusace_bark_quiet_thr_val[b_val1], iusace_bark_quiet_thr_val[b_val2]); + + ptr_thr_quiet[i] = (FLOAT32)pow(10.0f, (bark_thr_quiet - 20.0f) * (FLOAT32)0.1f) * 16887.8f * + (FLOAT32)(ptr_sfb_offset[i + 1] - ptr_sfb_offset[i]); + } + return; +} + +static VOID iusace_spreading_init(WORD32 sfb_count, FLOAT32 *ptr_bark_val, + FLOAT32 *ptr_mask_low_fac, FLOAT32 *ptr_mask_high_fac, + FLOAT32 *ptr_mask_low_fac_spr_energy, + FLOAT32 *ptr_mask_high_fac_spr_energy, const WORD32 bit_rate, + WORD32 block_type) { + WORD32 i; + FLOAT32 mask_low_spr_energy, mask_high_spr_energy; + + if (block_type != EIGHT_SHORT_SEQUENCE) { + mask_low_spr_energy = MASK_LOW_SP_ENERGY_L; + mask_high_spr_energy = (bit_rate > 22000) ? MASK_HIGH_SP_ENERGY_L : MASK_HIGH_SP_ENERGY_L_LBR; + } else { + mask_low_spr_energy = MASK_LOW_SP_ENERGY_S; + mask_high_spr_energy = MASK_HIGH_SP_ENERGY_S; + } + + for (i = 0; i < sfb_count; i++) { + if (i > 0) { + FLOAT32 db_val; + FLOAT32 diff_val = (ptr_bark_val[i] - ptr_bark_val[i - 1]); + + db_val = MASK_HIGH_FAC * diff_val; + ptr_mask_high_fac[i] = (FLOAT32)pow(10.0f, -db_val); + db_val = MASK_LOW_FAC * diff_val; + ptr_mask_low_fac[i - 1] = (FLOAT32)pow(10.0f, -db_val); + db_val = mask_high_spr_energy * diff_val; + ptr_mask_high_fac_spr_energy[i] = (FLOAT32)pow(10.0f, -db_val); + db_val = mask_low_spr_energy * diff_val; + ptr_mask_low_fac_spr_energy[i - 1] = (FLOAT32)pow(10.0f, -db_val); + } else { + ptr_mask_high_fac[i] = 0.0f; + ptr_mask_low_fac[sfb_count - 1] = 0.0f; + ptr_mask_high_fac_spr_energy[i] = 0.0f; + ptr_mask_low_fac_spr_energy[sfb_count - 1] = 0.0f; + } + } + return; +} + +static VOID iusace_min_snr_init(const WORD32 bit_rate, const WORD32 sample_rate, + const WORD32 num_lines, const WORD32 *ptr_sfb_offset, + const FLOAT32 *ptr_bark_value, const WORD32 sfb_active, + FLOAT32 *ptr_sfb_min_snr) { + WORD32 sfb; + FLOAT32 bark_fac; + FLOAT32 bark_width; + FLOAT32 pe_per_window, pe_part; + FLOAT32 snr; + FLOAT32 b_val0, b_val1; + + if (sfb_active == 0) { + bark_fac = 1.0f; + } else { + bark_fac = (FLOAT32)1.0 / MIN(ptr_bark_value[sfb_active - 1] / MAX_BARK_VALUE, (FLOAT32)1.0); + } + + pe_per_window = + iusace_bits_to_pe((FLOAT32)bit_rate / (FLOAT32)sample_rate * (FLOAT32)num_lines); + + b_val0 = (FLOAT32)0.0f; + + for (sfb = 0; sfb < sfb_active; sfb++) { + b_val1 = (FLOAT32)2.0 * ptr_bark_value[sfb] - b_val0; + bark_width = b_val1 - b_val0; + b_val0 = b_val1; + + pe_part = pe_per_window * (FLOAT32)0.024f * bark_fac; + pe_part *= bark_width; + pe_part /= (FLOAT32)(ptr_sfb_offset[sfb + 1] - ptr_sfb_offset[sfb]); + snr = (FLOAT32)pow(2.0f, pe_part) - 1.5f; + snr = 1.0f / MAX(snr, 1.0f); + snr = MIN(snr, 0.8f); + snr = MAX(snr, 0.003f); + ptr_sfb_min_snr[sfb] = snr; + } + return; +} + +VOID iusace_psy_long_config_init(WORD32 bit_rate, WORD32 sample_rate, WORD32 band_width, + ia_psy_mod_long_config_struct *pstr_psy_config, WORD32 ccfl) { + WORD32 sfb; + FLOAT32 sfb_bark_val[MAX_NUM_GROUPED_SFB]; + + iusace_sfb_init(sample_rate, ONLY_LONG_SEQUENCE, pstr_psy_config->sfb_offset, + &(pstr_psy_config->sfb_count), ccfl); + + iusace_bark_values_init(pstr_psy_config->sfb_count, pstr_psy_config->sfb_offset, + pstr_psy_config->sfb_offset[pstr_psy_config->sfb_count], sample_rate, + sfb_bark_val); + + iusace_thr_quiet_init(pstr_psy_config->sfb_count, pstr_psy_config->sfb_offset, sfb_bark_val, + pstr_psy_config->sfb_thr_quiet); + + iusace_spreading_init( + pstr_psy_config->sfb_count, sfb_bark_val, pstr_psy_config->sfb_mask_low_fac, + pstr_psy_config->sfb_mask_high_fac, pstr_psy_config->sfb_mask_low_fac_spr_ener, + pstr_psy_config->sfb_mask_high_fac_spr_ener, bit_rate, ONLY_LONG_SEQUENCE); + + pstr_psy_config->ratio = C_RATIO; + pstr_psy_config->max_allowed_inc_fac = 2.0f; + pstr_psy_config->min_remaining_thr_fac = 0.01f; + + pstr_psy_config->clip_energy = (CLIP_ENERGY_VALUE_LONG * ccfl) / FRAME_LEN_LONG; + pstr_psy_config->low_pass_line = (WORD32)((2 * band_width * ccfl) / sample_rate); + + for (sfb = 0; sfb < pstr_psy_config->sfb_count; sfb++) { + if (pstr_psy_config->sfb_offset[sfb] >= pstr_psy_config->low_pass_line) break; + } + pstr_psy_config->sfb_active = sfb; + + iusace_min_snr_init(bit_rate, sample_rate, + pstr_psy_config->sfb_offset[pstr_psy_config->sfb_count], + pstr_psy_config->sfb_offset, sfb_bark_val, pstr_psy_config->sfb_active, + pstr_psy_config->sfb_min_snr); + + return; +} + +VOID iusace_psy_short_config_init(WORD32 bit_rate, WORD32 sample_rate, WORD32 band_width, + ia_psy_mod_short_config_struct *pstr_psy_config, WORD32 ccfl) { + WORD32 sfb; + WORD32 frame_len_short = (ccfl * FRAME_LEN_SHORT_128) / FRAME_LEN_LONG; + FLOAT32 sfb_bark_val[MAX_NUM_GROUPED_SFB]; + + iusace_sfb_init(sample_rate, EIGHT_SHORT_SEQUENCE, pstr_psy_config->sfb_offset, + &(pstr_psy_config->sfb_count), ccfl); + + iusace_bark_values_init(pstr_psy_config->sfb_count, pstr_psy_config->sfb_offset, + pstr_psy_config->sfb_offset[pstr_psy_config->sfb_count], sample_rate, + sfb_bark_val); + + iusace_thr_quiet_init(pstr_psy_config->sfb_count, pstr_psy_config->sfb_offset, sfb_bark_val, + pstr_psy_config->sfb_thr_quiet); + + iusace_spreading_init( + pstr_psy_config->sfb_count, sfb_bark_val, pstr_psy_config->sfb_mask_low_fac, + pstr_psy_config->sfb_mask_high_fac, pstr_psy_config->sfb_mask_low_fac_spr_ener, + pstr_psy_config->sfb_mask_high_fac_spr_ener, bit_rate, EIGHT_SHORT_SEQUENCE); + + pstr_psy_config->ratio = C_RATIO; + pstr_psy_config->max_allowed_inc_fac = 2.0f; + pstr_psy_config->min_remaining_thr_fac = 0.01f; + + pstr_psy_config->clip_energy = + (CLIP_ENERGY_VALUE_SHORT * frame_len_short) / FRAME_LEN_SHORT_128; + pstr_psy_config->low_pass_line = (WORD32)((2 * band_width * frame_len_short) / sample_rate); + + for (sfb = 0; sfb < pstr_psy_config->sfb_count; sfb++) { + if (pstr_psy_config->sfb_offset[sfb] >= pstr_psy_config->low_pass_line) break; + } + pstr_psy_config->sfb_active = sfb; + + iusace_min_snr_init(bit_rate, sample_rate, + pstr_psy_config->sfb_offset[pstr_psy_config->sfb_count], + pstr_psy_config->sfb_offset, sfb_bark_val, pstr_psy_config->sfb_active, + pstr_psy_config->sfb_min_snr); + + return; +} + +IA_ERRORCODE iusace_sfb_params_init(WORD32 sample_rate, WORD32 frame_len, WORD32 *ptr_sfb_width, + WORD32 *num_sfb, WORD32 win_seq) { + WORD32 i, j, k; + ia_sfb_info_struct *ptr_sr_info = NULL; + WORD32 sampling_rate_mapped = 0; + + if (frame_len == 1024) { + ptr_sr_info = &iusace_sfb_info_1024[0]; + } else { + ptr_sr_info = &iusace_sfb_info_768[0]; + } + + if ((sample_rate >= 0) && (sample_rate < 9391)) { + sampling_rate_mapped = 8000; + } else if ((sample_rate >= 9391) && (sample_rate < 11502)) { + sampling_rate_mapped = 11025; + } else if ((sample_rate >= 11502) && (sample_rate < 13856)) { + sampling_rate_mapped = 12000; + } else if ((sample_rate >= 13856) && (sample_rate < 18783)) { + sampling_rate_mapped = 16000; + } else if ((sample_rate >= 18783) && (sample_rate < 23004)) { + sampling_rate_mapped = 22050; + } else if ((sample_rate >= 23004) && (sample_rate < 27713)) { + sampling_rate_mapped = 24000; + } else if ((sample_rate >= 27713) && (sample_rate < 37566)) { + sampling_rate_mapped = 32000; + } else if ((sample_rate >= 37566) && (sample_rate < 46009)) { + sampling_rate_mapped = 44100; + } else if ((sample_rate >= 46009) && (sample_rate < 55426)) { + sampling_rate_mapped = 48000; + } else if ((sample_rate >= 55426) && (sample_rate < 75132)) { + sampling_rate_mapped = 64000; + } else if ((sample_rate >= 75132) && (sample_rate < 92017)) { + sampling_rate_mapped = 88200; + } else if (sample_rate >= 92017) { + sampling_rate_mapped = 96000; + } else { + return -1; + } + + while (ptr_sr_info->sample_rate != sampling_rate_mapped) { + if (ptr_sr_info->sample_rate == -1) { + return -1; + } + ptr_sr_info++; + } + + j = 0; + for (i = 0; i < ptr_sr_info->num_sfb_long; i++) { + k = ptr_sr_info->cb_offset_long[i]; + ptr_sr_info->sfb_width_long[i] = k - j; + j = k; + } + j = 0; + for (i = 0; i < ptr_sr_info->num_sfb_short; i++) { + k = ptr_sr_info->cb_offset_short[i]; + ptr_sr_info->sfb_width_short[i] = k - j; + j = k; + } + + switch (win_seq) { + case EIGHT_SHORT_SEQUENCE: + memcpy(ptr_sfb_width, ptr_sr_info->sfb_width_short, (MAX_SFB_SHORT) * sizeof(WORD32)); + *num_sfb = ptr_sr_info->num_sfb_short; + break; + case ONLY_LONG_SEQUENCE: + case LONG_START_SEQUENCE: + case STOP_START_SEQUENCE: + case LONG_STOP_SEQUENCE: + default: + memcpy(ptr_sfb_width, ptr_sr_info->sfb_width_long, MAX_SFB_LONG * sizeof(WORD32)); + *num_sfb = ptr_sr_info->num_sfb_long; + break; + } + + return 0; +} diff --git a/encoder/iusace_psy_utils.h b/encoder/iusace_psy_utils.h new file mode 100644 index 0000000..691c656 --- /dev/null +++ b/encoder/iusace_psy_utils.h @@ -0,0 +1,45 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +typedef struct { + WORD32 sample_rate; + WORD32 num_sfb_long; + WORD32 num_sfb_short; + const WORD16 *cb_offset_long; + const WORD16 *cb_offset_short; + WORD32 sfb_width_long[MAX_SFB_LONG]; + WORD32 sfb_width_short[MAX_SFB_SHORT]; + +} ia_sfb_info_struct; + +VOID iusace_psy_long_config_init(WORD32 bit_rate, WORD32 sample_rate, WORD32 band_width, + ia_psy_mod_long_config_struct *pstr_psy_config, WORD32 ccfl); +VOID iusace_psy_short_config_init(WORD32 bit_rate, WORD32 sample_rate, WORD32 band_width, + ia_psy_mod_short_config_struct *pstr_psy_config, WORD32 ccfl); +VOID iusace_calc_band_energy(const FLOAT64 *ptr_spec_coeffs, const WORD32 *band_offset, + const WORD32 num_bands, FLOAT32 *ptr_band_energy, WORD32 sfb_count); +VOID iusace_find_max_spreading(const WORD32 sfb_count, const FLOAT32 *ptr_mask_low_fac, + const FLOAT32 *ptr_mask_high_fac, FLOAT32 *ptr_spreaded_enegry); +VOID iusace_pre_echo_control(FLOAT32 *ptr_thr_nm1, WORD32 sfb_count, FLOAT32 max_allowed_inc_fac, + FLOAT32 min_remaining_thr_fac, FLOAT32 *ptr_threshold); + +IA_ERRORCODE iusace_sfb_params_init(WORD32 sample_rate, WORD32 frame_len, WORD32 *ptr_sfb_width, + WORD32 *num_sfb, WORD32 win_seq); diff --git a/encoder/iusace_rom.c b/encoder/iusace_rom.c index 1f18388..9dce07f 100644 --- a/encoder/iusace_rom.c +++ b/encoder/iusace_rom.c @@ -20,9 +20,24 @@ #include "ixheaac_type_def.h" #include "iusace_cnst.h" +#include "iusace_block_switch_const.h" -const UWORD32 iusace_sampl_freq_table[] = {96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, - 16000, 12000, 11025, 8000, 7350, 0, 0, 0}; +const FLOAT32 iusace_iir_hipass_coeffs[BLK_SWITCH_FILT_LEN] = {-0.5095f, 0.7548f}; + +const WORD32 iusace_suggested_grouping_table[TRANS_FAC][MAXIMUM_NO_OF_GROUPS] = { + {1, 3, 3, 1}, {1, 1, 3, 3}, {2, 1, 3, 2}, {3, 1, 3, 1}, + {3, 1, 1, 3}, {3, 2, 1, 2}, {3, 3, 1, 1}, {3, 3, 1, 1}}; + +const WORD32 iusace_synchronized_block_types[4][4] = { + {LONG_WINDOW, START_WINDOW, SHORT_WINDOW, STOP_WINDOW}, + {START_WINDOW, START_WINDOW, SHORT_WINDOW, SHORT_WINDOW}, + {SHORT_WINDOW, SHORT_WINDOW, SHORT_WINDOW, SHORT_WINDOW}, + {STOP_WINDOW, SHORT_WINDOW, SHORT_WINDOW, STOP_WINDOW}}; + +const FLOAT32 iusace_gamma_table[ORDER + 1] = { + 1.0000f, 0.920000017f, 0.846400023f, 0.778688014f, 0.716392994f, 0.659081578f, + 0.606355071f, 0.557846665f, 0.513218939f, 0.472161442f, 0.434388548f, 0.399637461f, + 0.367666483f, 0.338253170f, 0.311192930f, 0.286297500f, 0.263393700f}; const FLOAT64 iusace_twiddle_table_fft_32x32[514] = { 1.00000000000000000000, 0.99998117528260111000, 0.99992470183914450000, @@ -585,6 +600,6850 @@ const FLOAT64 iusace_twiddle_table_3pr[1155] = { 1.00000000000000000000, 0.99986613790956180000, 0.99946458747636557000, 1.00000000000000000000, 1.00000000000000000000, 1.00000000000000000000}; +const FLOAT64 iusace_pre_post_twid_cos_2048[512] = { + 0.99999992646571789, 0.99999404372898582, 0.99997874866746883, 0.99995404142512978, + 0.99991992223452264, 0.99987639141679030, 0.99982344938166146, 0.99976109662744661, + 0.99968933374103364, 0.99960816139788211, 0.99951758036201710, 0.99941759148602183, + 0.99930819571102958, 0.99918939406671514, 0.99906118767128482, 0.99892357773146601, + 0.99877656554249594, 0.99862015248810920, 0.99845434004052513, 0.99827912976043365, + 0.99809452329698045, 0.99790052238775206, 0.99769712885875883, 0.99748434462441826, + 0.99726217168753650, 0.99703061213928990, 0.99678966815920500, 0.99653934201513839, + 0.99627963606325509, 0.99601055274800643, 0.99573209460210699, 0.99544426424651089, + 0.99514706439038714, 0.99484049783109385, 0.99452456745415241, 0.99419927623321958, + 0.99386462723006042, 0.99352062359451876, 0.99316726856448789, 0.99280456546587981, + 0.99243251771259433, 0.99205112880648649, 0.99166040233733399, 0.99126034198280311, + 0.99085095150841440, 0.99043223476750675, 0.99000419570120168, 0.98956683833836601, + 0.98912016679557357, 0.98866418527706723, 0.98819889807471861, 0.98772430956798807, + 0.98724042422388336, 0.98674724659691770, 0.98624478132906668, 0.98573303314972471, + 0.98521200687566068, 0.98468170741097227, 0.98414213974703990, 0.98359330896248010, + 0.98303522022309697, 0.98246787878183450, 0.98189128997872643, 0.98130545924084611, + 0.98071039208225541, 0.98010609410395322, 0.97949257099382214, 0.97886982852657556, + 0.97823787256370254, 0.97759670905341334, 0.97694634403058311, 0.97628678361669519, + 0.97561803401978331, 0.97494010153437338, 0.97425299254142417, 0.97355671350826711, + 0.97285127098854585, 0.97213667162215378, 0.97141292213517250, 0.97068002933980768, + 0.96993800013432552, 0.96918684150298762, 0.96842656051598486, 0.96765716432937154, + 0.96687866018499757, 0.96609105541044049, 0.96529435741893643, 0.96448857370931018, + 0.96367371186590500, 0.96284977955851081, 0.96201678454229234, 0.96117473465771586, + 0.96032363783047570, 0.95946350207141928, 0.95859433547647199, 0.95771614622656076, + 0.95682894258753726, 0.95593273291010006, 0.95502752562971593, 0.95411332926654058, + 0.95319015242533844, 0.95225800379540138, 0.95131689215046744, 0.95036682634863767, + 0.94940781533229346, 0.94843986812801151, 0.94746299384647970, 0.94647720168241067, + 0.94548250091445574, 0.94447890090511744, 0.94346641110066132, 0.94244504103102689, + 0.94141480030973834, 0.94037569863381365, 0.93932774578367351, 0.93827095162304930, + 0.93720532609889007, 0.93613087924126914, 0.93504762116328954, 0.93395556206098884, + 0.93285471221324323, 0.93174508198167072, 0.93062668181053376, 0.92949952222664056, + 0.92836361383924648, 0.92721896733995379, 0.92606559350261131, 0.92490350318321291, + 0.92373270731979529, 0.92255321693233483, 0.92136504312264444, 0.92016819707426845, + 0.91896269005237763, 0.91774853340366336, 0.91652573855623021, 0.91529431701948916, + 0.91405428038404857, 0.91280564032160560, 0.91154840858483599, 0.91028259700728376, + 0.90900821750324945, 0.90772528206767833, 0.90643380277604746, 0.90513379178425168, + 0.90382526132848950, 0.90250822372514794, 0.90118269137068652, 0.89984867674152069, + 0.89850619239390406, 0.89715525096381066, 0.89579586516681564, 0.89442804779797591, + 0.89305181173170944, 0.89166716992167439, 0.89027413540064659, 0.88887272128039763, + 0.88746294075157095, 0.88604480708355760, 0.88461833362437192, 0.88318353380052539, + 0.88174042111690032, 0.88028900915662289, 0.87882931158093536, 0.87736134212906713, + 0.87588511461810581, 0.87440064294286690, 0.87290794107576319, 0.87140702306667306, + 0.86989790304280845, 0.86838059520858191, 0.86685511384547254, 0.86532147331189191, + 0.86377968804304883, 0.86222977255081346, 0.86067174142358061, 0.85910560932613267, + 0.85753139099950138, 0.85594910126082913, 0.85435875500322966, 0.85276036719564763, + 0.85115395288271778, 0.84953952718462322, 0.84791710529695374, 0.84628670249056193, + 0.84464833411142004, 0.84300201558047516, 0.84134776239350428, 0.83968559012096844, + 0.83801551440786615, 0.83633755097358597, 0.83465171561175877, 0.83295802419010911, + 0.83125649265030566, 0.82954713700781135, 0.82782997335173236, 0.82610501784466717, + 0.82437228672255380, 0.82263179629451755, 0.82088356294271714, 0.81912760312219079, + 0.81736393336070101, 0.81559257025857934, 0.81381353048856986, 0.81202683079567239, + 0.81023248799698500, 0.80843051898154539, 0.80662094071017221, 0.80480377021530547, + 0.80297902460084580, 0.80114672104199391, 0.79930687678508872, 0.79745950914744512, + 0.79560463551719085, 0.79374227335310288, 0.79187244018444325, 0.78999515361079387, + 0.78811043130189085, 0.78621829099745844, 0.78431875050704170, 0.78241182770983930, + 0.78049754055453480, 0.77857590705912794, 0.77664694531076495, 0.77471067346556854, + 0.77276710974846674, 0.77081627245302142, 0.76885817994125616, 0.76689285064348356, + 0.76492030305813130, 0.76294055575156849, 0.76095362735793093, 0.75895953657894522, + 0.75695830218375337, 0.75494994300873552, 0.75293447795733315, 0.75091192599987089, + 0.74888230617337814, 0.74684563758140954, 0.74480193939386563, 0.74275123084681205, + 0.74069353124229864, 0.73862885994817784, 0.73655723639792214, 0.73447868009044137, + 0.73239321058989904, 0.73030084752552848, 0.72820161059144761, 0.72609551954647400, + 0.72398259421393862, 0.72186285448149945, 0.71973632030095414, 0.71760301168805218, + 0.71546294872230676, 0.71331615154680561, 0.71116264036802135, 0.70900243545562125, + 0.70683555714227686, 0.70466202582347193, 0.70248186195731099, 0.70029508606432678, + 0.69810171872728688, 0.69590178059099994, 0.69369529236212146, 0.69148227480895896, + 0.68926274876127669, 0.68703673511009888, 0.68480425480751383, 0.68256532886647647, + 0.68031997836061053, 0.67806822442400994, 0.67581008825104028, 0.67354559109613943, + 0.67127475427361694, 0.66899759915745383, 0.66671414718110111, 0.66442441983727873, + 0.66212843867777227, 0.65982622531323087, 0.65751780141296357, 0.65520318870473526, + 0.65288240897456229, 0.65055548406650732, 0.64822243588247386, 0.64588328638199977, + 0.64353805758205118, 0.64118677155681469, 0.63882945043748984, 0.63646611641208073, + 0.63409679172518729, 0.63172149867779581, 0.62934025962706919, 0.62695309698613622, + 0.62456003322388076, 0.62216109086473037, 0.61975629248844410, 0.61734566072990027, + 0.61492921827888303, 0.61250698787986901, 0.61007899233181317, 0.60764525448793427, + 0.60520579725549994, 0.60276064359561066, 0.60030981652298387, 0.59785333910573735, + 0.59539123446517217, 0.59292352577555474, 0.59045023626389925, 0.58797138920974845, + 0.58548700794495490, 0.58299711585346126, 0.58050173637108005, 0.57800089298527335, + 0.57549460923493156, 0.57298290871015189, 0.57046581505201632, 0.56794335195236889, + 0.56541554315359299, 0.56288241244838777, 0.56034398367954408, 0.55780028073972032, + 0.55525132757121742, 0.55269714816575322, 0.55013776656423696, 0.54757320685654309, + 0.54500349318128438, 0.54242864972558458, 0.53984870072485092, 0.53726367046254586, + 0.53467358326995873, 0.53207846352597676, 0.52947833565685520, 0.52687322413598792, + 0.52426315348367658, 0.52164814826690020, 0.51902823309908397, 0.51640343263986710, + 0.51377377159487125, 0.51113927471546750, 0.50849996679854403, 0.50585587268627197, + 0.50320701726587214, 0.50055342546938053, 0.49789512227341393, 0.49523213269893424, + 0.49256448181101364, 0.48989219471859818, 0.48721529657427176, 0.48453381257401917, + 0.48184776795698908, 0.47915718800525636, 0.47646209804358425, 0.47376252343918585, + 0.47105848960148550, 0.46835002198187953, 0.46563714607349660, 0.46291988741095808, + 0.46019827157013726, 0.45747232416791900, 0.45474207086195839, 0.45200753735043936, + 0.44926874937183281, 0.44652573270465423, 0.44377851316722111, 0.44102711661741012, + 0.43827156895241337, 0.43551189610849489, 0.43274812406074659, 0.42998027882284351, + 0.42720838644679915, 0.42443247302272025, 0.42165256467856116, 0.41886868757987789, + 0.41608086792958199, 0.41328913196769368, 0.41049350597109513, 0.40769401625328289, + 0.40489068916412035, 0.40208355108958971, 0.39927262845154365, 0.39645794770745657, + 0.39363953535017560, 0.39081741790767122, 0.38799162194278758, 0.38516217405299252, + 0.38232910087012717, 0.37949242906015523, 0.37665218532291223, 0.37380839639185381, + 0.37096108903380454, 0.36811029004870566, 0.36525602626936288, 0.36239832456119392, + 0.35953721182197568, 0.35667271498159087, 0.35380486100177466, 0.35093367687586097, + 0.34805918962852822, 0.34518142631554516, 0.34230041402351608, 0.33941617986962591, + 0.33652875100138496, 0.33363815459637342, 0.33074441786198550, 0.32784756803517340, + 0.32494763238219099, 0.32204463819833706, 0.31913861280769845, 0.31622958356289288, + 0.31331757784481157, 0.31040262306236127, 0.30748474665220660, 0.30456397607851154, + 0.30164033883268121, 0.29871386243310277, 0.29578457442488665, 0.29285250237960719, + 0.28991767389504314, 0.28698011659491790, 0.28403985812863958, 0.28109692617104060, + 0.27815134842211742, 0.27520315260676959, 0.27225236647453899, 0.26929901779934839, + 0.26634313437924040, 0.26338474403611545, 0.26042387461547023, 0.25746055398613527, + 0.25449481004001295, 0.25152667069181478, 0.24855616387879872, 0.24558331756050619, + 0.24260815971849894, 0.23963071835609570, 0.23665102149810846, 0.23366909719057891, + 0.23068497350051426, 0.22769867851562317, 0.22471024034405140, 0.22171968711411716, + 0.21872704697404638, 0.21573234809170780, 0.21273561865434781, 0.20973688686832517, + 0.20673618095884555, 0.20373352916969573, 0.20072895976297794, 0.19772250101884370, + 0.19471418123522771, 0.19170402872758152, 0.18869207182860689, 0.18567833888798929, + 0.18266285827213094, 0.17964565836388377, 0.17662676756228246, 0.17360621428227699, + 0.17058402695446515, 0.16756023402482509, 0.16453486395444747, 0.16150794521926759, + 0.15847950630979737, 0.15544957573085721, 0.15241818200130769, 0.14938535365378106, + 0.14635111923441280, 0.14331550730257281, 0.14027854643059670, 0.13724026520351684, + 0.13420069221879324, 0.13115985608604447, 0.12811778542677829, 0.12507450887412230, + 0.12203005507255447, 0.11898445267763344, 0.11593773035572885, 0.11288991678375154, + 0.10984104064888360, 0.10679113064830836, 0.10374021548894032, 0.10068832388715487, + 0.09763548456851809, 0.09458172626751629, 0.09152707772728565, 0.08847156769934156, + 0.08541522494330810, 0.08235807822664729, 0.07930015632438830, 0.07624148801885673, + 0.07318210209940354, 0.07012202736213415, 0.06706129260963742, 0.06399992665071451, + 0.06093795830010773, 0.05787541637822936, 0.05481232971089032, 0.05174872712902889, + 0.04868463746843935, 0.04562008956950053, 0.04255511227690437, 0.03948973443938444, + 0.03642398490944440, 0.03335789254308640, 0.03029148619953951, 0.02722479474098807, + 0.02415784703230002, 0.02109067194075525, 0.01802329833577384, 0.01495575508864437, + 0.01188807107225213, 0.00882027516080741, 0.00575239622957371, 0.00268446315459590}; +const FLOAT64 iusace_pre_post_twid_sin_2048[512] = { + 0.00038349518757140, 0.00345144992013600, 0.00651937216633947, 0.00958723304972923, + 0.01265500369443025, 0.01572265522541687, 0.01879015876878457, 0.02185748545202175, + 0.02492460640428148, 0.02799149275665326, 0.03105811564243472, 0.03412444619740334, + 0.03719045556008814, 0.04025611487204131, 0.04332139527810985, 0.04638626792670719, + 0.04945070397008470, 0.05251467456460325, 0.05557815087100472, 0.05864110405468338, + 0.06170350528595735, 0.06476532574033993, 0.06782653659881092, 0.07088710904808787, + 0.07394701428089727, 0.07700622349624571, 0.08006470789969096, 0.08312243870361301, + 0.08617938712748499, 0.08923552439814411, 0.09229082175006245, 0.09534525042561773, + 0.09839878167536399, 0.10145138675830218, 0.10450303694215067, 0.10755370350361573, + 0.11060335772866185, 0.11365197091278199, 0.11669951436126781, 0.11974595938947973, + 0.12279127732311691, 0.12583543949848716, 0.12887841726277668, 0.13192018197431993, + 0.13496070500286894, 0.13799995772986298, 0.14103791154869791, 0.14407453786499538, + 0.14710980809687202, 0.15014369367520844, 0.15317616604391809, 0.15620719666021618, + 0.15923675699488812, 0.16226481853255831, 0.16529135277195828, 0.16831633122619516, + 0.17133972542301965, 0.17436150690509411, 0.17738164723026043, 0.18040011797180761, + 0.18341689071873948, 0.18643193707604203, 0.18944522866495064, 0.19245673712321729, + 0.19546643410537742, 0.19847429128301683, 0.20148028034503820, 0.20448437299792768, + 0.20748654096602112, 0.21048675599177022, 0.21348498983600853, 0.21648121427821723, + 0.21947540111679079, 0.22246752216930235, 0.22545754927276904, 0.22844545428391699, + 0.23143120907944631, 0.23441478555629572, 0.23739615563190714, 0.24037529124449000, + 0.24335216435328530, 0.24632674693882961, 0.24929901100321877, 0.25226892857037142, + 0.25523647168629232, 0.25820161241933548, 0.26116432286046709, 0.26412457512352816, + 0.26708234134549691, 0.27003759368675123, 0.27299030433133059, 0.27594044548719787, + 0.27888798938650095, 0.28183290828583407, 0.28477517446649903, 0.28771476023476594, + 0.29065163792213400, 0.29358577988559198, 0.29651715850787819, 0.29944574619774067, + 0.30237151539019669, 0.30529443854679245, 0.30821448815586189, 0.31113163673278604, + 0.31404585682025149, 0.31695712098850898, 0.31986540183563128, 0.32277067198777154, + 0.32567290409942062, 0.32857207085366458, 0.33146814496244176, 0.33436109916679962, + 0.33725090623715154, 0.34013753897353272, 0.34302097020585648, 0.34590117279416999, + 0.34877811962890948, 0.35165178363115568, 0.35452213775288854, 0.35738915497724200, + 0.36025280831875794, 0.36311307082364058, 0.36596991557000991, 0.36882331566815507, + 0.37167324426078768, 0.37451967452329443, 0.37736257966398962, 0.38020193292436733, + 0.38303770757935335, 0.38586987693755659, 0.38869841434152047, 0.39152329316797374, + 0.39434448682808099, 0.39716196876769300, 0.39997571246759678, 0.40278569144376497, + 0.40559187924760531, 0.40839424946620950, 0.41119277572260166, 0.41398743167598695, + 0.41677819102199914, 0.41956502749294844, 0.42234791485806861, 0.42512682692376391, + 0.42790173753385569, 0.43067262056982841, 0.43343944995107569, 0.43620219963514562, + 0.43896084361798599, 0.44171535593418898, 0.44446571065723567, 0.44721188189973993, + 0.44995384381369213, 0.45269157059070253, 0.45542503646224403, 0.45815421569989478, + 0.46087908261558042, 0.46359961156181573, 0.46631577693194620, 0.46902755316038891, + 0.47173491472287327, 0.47443783613668106, 0.47713629196088664, 0.47983025679659602, + 0.48251970528718618, 0.48520461211854371, 0.48788495201930293, 0.49056069976108391, + 0.49323183015872984, 0.49589831807054413, 0.49856013839852703, 0.50121726608861183, + 0.50386967613090083, 0.50651734355990052, 0.50916024345475663, 0.51179835093948889, + 0.51443164118322482, 0.51706008940043391, 0.51968367085116052, 0.52230236084125670, + 0.52491613472261500, 0.52752496789340020, 0.53012883579828096, 0.53272771392866081, + 0.53532157782290912, 0.53791040306659099, 0.54049416529269723, 0.54307284018187385, + 0.54564640346265059, 0.54821483091166989, 0.55077809835391434, 0.55333618166293441, + 0.55588905676107592, 0.55843669961970621, 0.56097908625944037, 0.56351619275036702, + 0.56604799521227367, 0.56857446981487136, 0.57109559277801891, 0.57361134037194683, + 0.57612168891748061, 0.57862661478626365, 0.58112609440097984, 0.58362010423557498, + 0.58610862081547876, 0.58859162071782523, 0.59106908057167373, 0.59354097705822872, + 0.59600728691105886, 0.59846798691631675, 0.60092305391295653, 0.60337246479295281, + 0.60581619650151741, 0.60825422603731694, 0.61068653045268873, 0.61311308685385746, + 0.61553387240114998, 0.61794886430921081, 0.62035803984721649, 0.62276137633908923, + 0.62515885116371051, 0.62755044175513441, 0.62993612560279932, 0.63231588025174046, + 0.63468968330280062, 0.63705751241284148, 0.63941934529495359, 0.64177515971866650, + 0.64412493351015754, 0.64646864455246089, 0.64880627078567565, 0.65113779020717344, + 0.65346318087180544, 0.65578242089210914, 0.65809548843851429, 0.66040236173954814, + 0.66270301908204055, 0.66499743881132856, 0.66728559933145970, 0.66956747910539571, + 0.67184305665521515, 0.67411231056231558, 0.67637521946761492, 0.67863176207175269, + 0.68088191713529045, 0.68312566347891190, 0.68536297998362183, 0.68759384559094539, + 0.68981823930312569, 0.69203614018332194, 0.69424752735580653, 0.69645238000616105, + 0.69865067738147280, 0.70084239879052956, 0.70302752360401466, 0.70520603125470116, + 0.70737790123764555, 0.70954311311038021, 0.71170164649310641, 0.71385348106888591, + 0.71599859658383214, 0.71813697284730105, 0.72026858973208063, 0.72239342717458110, + 0.72451146517502318, 0.72662268379762651, 0.72872706317079738, 0.73082458348731572, + 0.73291522500452144, 0.73499896804450038, 0.73707579299426940, 0.73914568030596128, + 0.74120861049700815, 0.74326456415032549, 0.74531352191449440, 0.74735546450394419, + 0.74939037269913356, 0.75141822734673147, 0.75343900935979768, 0.75545269971796236, + 0.75745927946760483, 0.75945872972203243, 0.76145103166165784, 0.76343616653417634, + 0.76541411565474249, 0.76738486040614595, 0.76934838223898661, 0.77130466267184905, + 0.77325368329147692, 0.77519542575294575, 0.77712987177983606, 0.77905700316440507, + 0.78097680176775830, 0.78288924952002004, 0.78479432842050378, 0.78669202053788134, + 0.78858230801035178, 0.79046517304580943, 0.79234059792201161, 0.79420856498674519, + 0.79606905665799266, 0.79792205542409766, 0.79976754384393034, 0.80160550454705082, + 0.80343592023387289, 0.80525877367582710, 0.80707404771552249, 0.80888172526690849, + 0.81068178931543566, 0.81247422291821547, 0.81425900920418026, 0.81603613137424180, + 0.81780557270144938, 0.81956731653114734, 0.82132134628113185, 0.82306764544180677, + 0.82480619757633955, 0.82653698632081518, 0.82825999538439088, 0.82997520854944917, + 0.83168260967175045, 0.83338218268058517, 0.83507391157892485, 0.83675778044357274, + 0.83843377342531389, 0.84010187474906395, 0.84176206871401804, 0.84341433969379842, + 0.84505867213660113, 0.84669505056534311, 0.84832345957780730, 0.84994388384678798, + 0.85155630812023475, 0.85316071722139630, 0.85475709604896299, 0.85634542957720949, + 0.85792570285613567, 0.85949790101160761, 0.86106200924549747, 0.86261801283582284, + 0.86416589713688530, 0.86570564757940838, 0.86723724967067450, 0.86876068899466141, + 0.87027595121217804, 0.87178302206099934, 0.87328188735600043, 0.87477253298929036, + 0.87625494493034473, 0.87772910922613778, 0.87919501200127370, 0.88065263945811734, + 0.88210197787692390, 0.88354301361596821, 0.88497573311167310, 0.88640012287873704, + 0.88781616951026099, 0.88922385967787476, 0.89062318013186237, 0.89201411770128691, + 0.89339665929411416, 0.89477079189733610, 0.89613650257709343, 0.89749377847879686, + 0.89884260682724892, 0.90018297492676347, 0.90151487016128540, 0.90283827999450950, + 0.90415319196999855, 0.90545959371130014, 0.90675747292206343, 0.90804681738615511, + 0.90932761496777414, 0.91059985361156581, 0.91186352134273541, 0.91311860626716101, + 0.91436509657150544, 0.91560298052332711, 0.91683224647119088, 0.91805288284477737, + 0.91926487815499236, 0.92046822099407410, 0.92166290003570184, 0.92284890403510123, + 0.92402622182915095, 0.92519484233648763, 0.92635475455760996, 0.92750594757498239, + 0.92864841055313774, 0.92978213273877941, 0.93090710346088235, 0.93202331213079370, + 0.93313074824233244, 0.93422940137188804, 0.93531926117851893, 0.93640031740404939, + 0.93747255987316658, 0.93853597849351600, 0.93959056325579660, 0.94063630423385491, + 0.94167319158477869, 0.94270121554898922, 0.94372036645033353, 0.94473063469617513, + 0.94573201077748448, 0.94672448526892861, 0.94770804882895954, 0.94868269219990253, + 0.94964840620804303, 0.95060518176371278, 0.95155300986137603, 0.95249188157971376, + 0.95342178808170774, 0.95434272061472381, 0.95525467051059432, 0.95615762918569958, + 0.95705158814104840, 0.95793653896235886, 0.95881247332013675, 0.95967938296975419, + 0.96053725975152748, 0.96138609559079369, 0.96222588249798657, 0.96305661256871189, + 0.96387827798382186, 0.96469087100948869, 0.96549438399727727, 0.96628880938421735, + 0.96707413969287470, 0.96785036753142129, 0.96861748559370520, 0.96937548665931905, + 0.97012436359366805, 0.97086410934803735, 0.97159471695965804, 0.97231617955177319, + 0.97302849033370198, 0.97373164260090417, 0.97442562973504276, 0.97511044520404666, + 0.97578608256217170, 0.97645253545006194, 0.97710979759480887, 0.97775786281001087, + 0.97839672499583130, 0.97902637813905580, 0.97964681631314943, 0.98025803367831177, + 0.98086002448153209, 0.98145278305664374, 0.98203630382437723, 0.98261058129241297, + 0.98317561005543264, 0.98373138479517042, 0.98427790028046269, 0.98481515136729758, + 0.98534313299886322, 0.98586184020559542, 0.98637126810522446, 0.98687141190282091, + 0.98736226689084094, 0.98784382844917040, 0.98831609204516835, 0.98877905323371018, + 0.98923270765722882, 0.98967705104575598, 0.99011207921696254, 0.99053778807619763, + 0.99095417361652738, 0.99136123191877246, 0.99175895915154511, 0.99214735157128509, + 0.99252640552229521, 0.99289611743677508, 0.99325648383485554, 0.99360750132463072, + 0.99394916660219035, 0.99428147645165066, 0.99460442774518487, 0.99491801744305242, + 0.99522224259362757, 0.99551710033342733, 0.99580258788713849, 0.99607870256764330, + 0.99634544177604534, 0.99660280300169357, 0.99685078382220604, 0.99708938190349294, + 0.99731859499977815, 0.99753842095362089, 0.99774885769593535, 0.99794990324601085, + 0.99814155571153018, 0.99832381328858721, 0.99849667426170441, 0.99866013700384826, + 0.99881419997644527, 0.99895886172939607, 0.99909412090108918, 0.99921997621841363, + 0.99933642649677135, 0.99944347064008787, 0.99954110764082305, 0.99962933657998021, + 0.99970815662711499, 0.99977756704034304, 0.99983756716634720, 0.99988815644038342, + 0.99992933438628617, 0.99996110061647292, 0.99998345483194784, 0.99999639682230457}; + +const FLOAT64 iexheaac_pre_post_twid_cos_1536[384] = { + 0.99999986927238849, 0.99998941108192840, 0.99996221995735501, 0.99991829635366070, + 0.99985764100582386, 0.99978025492879719, 0.99968613941749052, 0.99957529604674922, + 0.99944772667132775, 0.99930343342585870, 0.99914241872481691, 0.99896468526247939, + 0.99877023601287984, 0.99855907422975931, 0.99833120344651138, 0.99808662747612309, + 0.99782535041111164, 0.99754737662345505, 0.99725271076451960, 0.99694135776498216, + 0.99661332283474680, 0.99626861146285883, 0.99590722941741172, 0.99552918274545166, + 0.99513447777287556, 0.99472312110432570, 0.99429511962307904, 0.99385048049093205, + 0.99338921114808065, 0.99291131931299614, 0.99241681298229589, 0.99190570043060933, + 0.99137799021043960, 0.99083369115202069, 0.99027281236316911, 0.98969536322913221, + 0.98910135341243055, 0.98849079285269659, 0.98786369176650812, 0.98722006064721735, + 0.98655991026477541, 0.98588325166555224, 0.98519009617215136, 0.98448045538322093, + 0.98375434117325911, 0.98301176569241588, 0.98225274136628937, 0.98147728089571817, + 0.98068539725656856, 0.97987710369951764, 0.97905241374983154, 0.97821134120713882, + 0.97735390014519996, 0.97648010491167192, 0.97558997012786730, 0.97468351068851067, + 0.97376074176148875, 0.97282167878759651, 0.97186633748027940, 0.97089473382536973, + 0.96990688408081971, 0.96890280477642887, 0.96788251271356818, 0.96684602496489813, + 0.96579335887408368, 0.96472453205550357, 0.96363956239395610, 0.96253846804435916, + 0.96142126743144718, 0.96028797924946241, 0.95913862246184189, 0.95797321630090093, + 0.95679178026751044, 0.95559433413077111, 0.95438089792768221, 0.95315149196280702, + 0.95190613680793235, 0.95064485330172444, 0.94936766254938076, 0.94807458592227623, + 0.94676564505760596, 0.94544086185802323, 0.94410025849127266, 0.94274385738981958, + 0.94137168125047466, 0.93998375303401405, 0.93858009596479475, 0.93716073353036700, + 0.93572568948108037, 0.93427498782968654, 0.93280865285093773, 0.93132670908118043, + 0.92982918131794468, 0.92831609461952902, 0.92678747430458175, 0.92524334595167679, + 0.92368373539888560, 0.92210866874334518, 0.92051817234082112, 0.91891227280526677, + 0.91729099700837791, 0.91565437207914280, 0.91400242540338861, 0.91233518462332275, + 0.91065267763707092, 0.90895493259820970, 0.90724197791529593, 0.90551384225139064, + 0.90377055452358057, 0.90201214390249318, 0.90023863981180907, 0.89845007192776960, + 0.89664647017868015, 0.89482786474440978, 0.89299428605588527, 0.89114576479458318, + 0.88928233189201544, 0.88740401852921214, 0.88551085613619995, 0.88360287639147572, + 0.88168011122147705, 0.87974259280004741, 0.87779035354789825, 0.87582342613206632, + 0.87384184346536686, 0.87184563870584320, 0.86983484525621180, 0.86780949676330332, + 0.86576962711749927, 0.86371527045216578, 0.86164646114308130, 0.85956323380786248, + 0.85746562330538401, 0.85535366473519603, 0.85322739343693621, 0.85108684498973897, + 0.84893205521163961, 0.84676306015897540, 0.84457989612578188, 0.84238259964318585, + 0.84017120747879392, 0.83794575663607729, 0.83570628435375260, 0.83345282810515875, + 0.83118542559762998, 0.82890411477186499, 0.82660893380129130, 0.82429992109142802, + 0.82197711527924155, 0.81964055523250012, 0.81729028004912307, 0.81492632905652662, + 0.81254874181096581, 0.81015755809687262, 0.80775281792619036, 0.80533456153770389, + 0.80290282939636648, 0.80045766219262282, 0.79799910084172765, 0.79552718648306198, + 0.79304196047944375, 0.79054346441643619, 0.78803174010165211, 0.78550682956405393, + 0.78296877505325091, 0.78041761903879148, 0.77785340420945315, 0.77527617347252809, + 0.77268596995310512, 0.77008283699334801, 0.76746681815177020, 0.76483795720250614, + 0.76219629813457890, 0.75954188515116350, 0.75687476266884779, 0.75419497531688917, + 0.75150256793646764, 0.74879758557993559, 0.74608007351006389, 0.74335007719928425, + 0.74060764232892895, 0.73785281478846598, 0.73508564067473114, 0.73230616629115663, + 0.72951443814699701, 0.72671050295654982, 0.72389440763837476, 0.72106619931450811, + 0.71822592530967466, 0.71537363315049540, 0.71250937056469232, 0.70963318548029031, + 0.70674512602481443, 0.70384524052448494, 0.70093357750340868, 0.69801018568276718, + 0.69507511398000088, 0.69212841150799143, 0.68917012757423934, 0.68620031168003870, + 0.68321901351964942, 0.68022628297946575, 0.67722217013718045, 0.67420672526094838, + 0.67117999880854418, 0.66814204142651856, 0.66509290394935028, 0.66203263739859630, + 0.65896129298203743, 0.65587892209282139, 0.65278557630860357, 0.64968130739068330, + 0.64656616728313754, 0.64344020811195279, 0.64030348218415167, 0.63715604198691822, + 0.63399794018671951, 0.63082922962842447, 0.62764996333441980, 0.62446019450372181, + 0.62125997651108766, 0.61804936290612111, 0.61482840741237699, 0.61159716392646191, + 0.60835568651713290, 0.60510402942439234, 0.60184224705858003, 0.59857039399946343, + 0.59528852499532403, 0.59199669496204099, 0.58869495898217261, 0.58538337230403481, + 0.58206199034077566, 0.57873086866944934, 0.57539006303008555, 0.57203962932475705, + 0.56867962361664381, 0.56531010212909516, 0.56193112124468947, 0.55854273750428962, + 0.55514500760609820, 0.55173798840470756, 0.54832173691014907, 0.54489631028693941, + 0.54146176585312344, 0.53801816107931555, 0.53456555358773761, 0.53110400115125500, + 0.52763356169240982, 0.52415429328245211, 0.52066625414036727, 0.51716950263190220, + 0.51366409726858941, 0.51015009670676692, 0.50662755974659701, 0.50309654533108283, + 0.49955711254508189, 0.49600932061431663, 0.49245322890438414, 0.48888889691976323, + 0.48531638430281743, 0.48173575083279779, 0.47814705642484312, 0.47455036112897614, + 0.47094572512909938, 0.46733320874198853, 0.46371287241628206, 0.46008477673147102, + 0.45644898239688386, 0.45280555025067232, 0.44915454125879173, 0.44549601651398174, + 0.44183003723474451, 0.43815666476431908, 0.43447596056965571, 0.43078798624038772, + 0.42709280348779960, 0.42339047414379610, 0.41968106015986573, 0.41596462360604591, + 0.41224122666988300, 0.40851093165539210, 0.40477380098201526, 0.40102989718357579, + 0.39727928290723241, 0.39352202091243177, 0.38975817406985663, 0.38598780536037502, + 0.38221097787398639, 0.37842775480876562, 0.37463819946980509, 0.37084237526815589, + 0.36704034571976724, 0.36323217444442257, 0.35941792516467541, 0.35559766170478396, + 0.35177144798964166, 0.34793934804370824, 0.34410142598993876, 0.34025774604871040, + 0.33640837253674716, 0.33255336986604422, 0.32869280254279076, 0.32482673516628924, + 0.32095523242787521, 0.31707835910983528, 0.31319618008432198, 0.30930876031226878, + 0.30541616484230355, 0.30151845880965988, 0.29761570743508631, 0.29370797602375576, + 0.28979532996417329, 0.28587783472708073, 0.28195555586436161, 0.27802855900794510, + 0.27409690986870655, 0.27016067423536833, 0.26621991797339978, 0.26227470702391359, + 0.25832510740256420, 0.25437118519844121, 0.25041300657296528, 0.24645063775877973, + 0.24248414505864274, 0.23851359484431850, 0.23453905355546548, 0.23056058769852522, + 0.22657826384561011, 0.22259214863338800, 0.21860230876196879, 0.21460881099378670, + 0.21061172215248500, 0.20661110912179528, 0.20260703884442133, 0.19859957832091624, + 0.19458879460856324, 0.19057475482025280, 0.18655752612335899, 0.18253717573861739, + 0.17851377093899759, 0.17448737904858050, 0.17045806744142938, 0.16642590354046422, + 0.16239095481633189, 0.15835328878627919, 0.15431297301302024, 0.15027007510360904, + 0.14622466270830650, 0.14217680351944800, 0.13812656527031236, 0.13407401573398653, + 0.13001922272223357, 0.12596225408435541, 0.12190317770606043, 0.11784206150832502, + 0.11377897344625872, 0.10971398150796650, 0.10564715371341048, 0.10157855811327342, + 0.09750826278781743, 0.09343633584574791, 0.08936284542307112, 0.08528785968195610, + 0.08121144680959239, 0.07713367501705092, 0.07305461253814007, 0.06897432762826673, + 0.06489288856329267, 0.06081036363839155, 0.05672682116690778, 0.05264232947921158, + 0.04855695692155763, 0.04447077185493874, 0.04038384265394508, 0.03629623770561741, + 0.03220802540830470, 0.02811927417051791, 0.02403005240978677, 0.01994042855151460, + 0.01585047102783169, 0.01176024827645315, 0.00766982873953108, 0.00357928086251129, +}; + +const FLOAT64 iexheaac_pre_post_twid_sin_1536[384] = { + 0.00051132690701370, 0.00460192612044857, 0.00869244832934148, 0.01278282508652904, + 0.01687298794728171, 0.02096286847044912, 0.02505239821960527, 0.02914150876419372, + 0.03323013168067260, 0.03731819855365960, 0.04140564097707674, 0.04549239055529501, + 0.04957837890427887, 0.05366353765273053, 0.05774779844323395, 0.06183109293339877, + 0.06591335279700380, 0.06999450972514044, 0.07407449542735553, 0.07815324163279423, + 0.08223068009134235, 0.08630674257476834, 0.09038136087786500, 0.09445446681959072, + 0.09852599224421053, 0.10259586902243628, 0.10666402905256692, 0.11073040426162782, + 0.11479492660651008, 0.11885752807510891, 0.12291814068746176, 0.12697669649688584, + 0.13103312759111516, 0.13508736609343663, 0.13913934416382620, 0.14318899400008386, + 0.14723624783896819, 0.15128103795733022, 0.15532329667324671, 0.15936295634715270, + 0.16339994938297323, 0.16743420822925453, 0.17146566538029431, 0.17549425337727143, + 0.17951990480937446, 0.18354255231492997, 0.18756212858252960, 0.19157856635215620, + 0.19559179841630961, 0.19960175762113097, 0.20360837686752664, 0.20761158911229086, + 0.21161132736922755, 0.21560752471027131, 0.21960011426660728, 0.22358902922978996, + 0.22757420285286145, 0.23155556845146782, 0.23553305940497549, 0.23950660915758562, + 0.24347615121944791, 0.24744161916777327, 0.25140294664794521, 0.25536006737463002, + 0.25931291513288623, 0.26326142377927236, 0.26720552724295366, 0.27114515952680801, + 0.27508025470852987, 0.27901074694173367, 0.28293657045705539, 0.28685765956325310, + 0.29077394864830647, 0.29468537218051433, 0.29859186470959143, 0.30249336086776346, + 0.30638979537086092, 0.31028110301941170, 0.31416721869973174, 0.31804807738501495, + 0.32192361413642090, 0.32579376410416178, 0.32965846252858749, 0.33351764474126916, + 0.33737124616608133, 0.34121920232028236, 0.34506144881559370, 0.34889792135927727, + 0.35272855575521073, 0.35655328790496249, 0.36037205380886383, 0.36418478956707984, + 0.36799143138067886, 0.37179191555269947, 0.37558617848921722, 0.37937415670040803, + 0.38315578680161094, 0.38693100551438858, 0.39069974966758603, 0.39446195619838792, + 0.39821756215337356, 0.40196650468957063, 0.40570872107550643, 0.40944414869225759, + 0.41317272503449815, 0.41689438771154497, 0.42060907444840251, 0.42431672308680402, + 0.42801727158625225, 0.43171065802505731, 0.43539682060137269, 0.43907569763422988, + 0.44274722756457002, 0.44641134895627410, 0.45006800049719120, 0.45371712100016387, + 0.45735864940405274, 0.46099252477475772, 0.46461868630623776, 0.46823707332152847, + 0.47184762527375707, 0.47545028174715587, 0.47904498245807325, 0.48263166725598206, + 0.48621027612448642, 0.48978074918232578, 0.49334302668437718, 0.49689704902265447, + 0.50044275672730665, 0.50398009046761183, 0.50750899105297087, 0.51102939943389758, + 0.51454125670300643, 0.51804450409599934, 0.52153908299264751, 0.52502493491777324, + 0.52850200154222848, 0.53197022468387023, 0.53542954630853479, 0.53887990853100842, + 0.54232125361599592, 0.54575352397908705, 0.54917666218771966, 0.55259061096214135, + 0.55599531317636719, 0.55939071185913603, 0.56277675019486395, 0.56615337152459444, + 0.56952051934694714, 0.57287813731906279, 0.57622616925754588, 0.57956455913940574, + 0.58289325110299262, 0.58621218944893361, 0.58952131864106394, 0.59282058330735632, + 0.59610992824084830, 0.59938929840056454, 0.60265863891243943, 0.60591789507023441, + 0.60916701233645310, 0.61240593634325502, 0.61563461289336407, 0.61885298796097632, + 0.62206100769266337, 0.62525861840827412, 0.62844576660183271, 0.63162239894243344, + 0.63478846227513386, 0.63794390362184394, 0.64108867018221261, 0.64422270933451053, + 0.64734596863651206, 0.65045839582637166, 0.65355993882349872, 0.65665054572942894, + 0.65973016482869329, 0.66279874458968246, 0.66585623366550961, 0.66890258089486998, + 0.67193773530289636, 0.67496164610201204, 0.67797426269278105, 0.68097553466475491, + 0.68396541179731540, 0.68694384406051590, 0.68991078161591779, 0.69286617481742463, + 0.69580997421211321, 0.69874213054106049, 0.70166259474016845, 0.70457131794098460, + 0.70746825147151948, 0.71035334685706231, 0.71322655582099082, 0.71608783028557954, + 0.71893712237280438, 0.72177438440514397, 0.72459956890637656, 0.72741262860237577, + 0.73021351642190047, 0.73300218549738294, 0.73577858916571348, 0.73854268096902032, + 0.74129441465544754, 0.74403374417992918, 0.74676062370495966, 0.74947500760136010, + 0.75217685044904270, 0.75486610703777046, 0.75754273236791358, 0.76020668165120231, + 0.76285791031147721, 0.76549637398543358, 0.76812202852336542, 0.77073482998990284, + 0.77333473466474845, 0.77592169904340758, 0.77849567983791756, 0.78105663397757141, + 0.78360451860963820, 0.78613929110008096, 0.78866090903426944, 0.79116933021769020, + 0.79366451267665228, 0.79614641465898983, 0.79861499463476082, 0.80107021129694189, + 0.80351202356211904, 0.80594039057117628, 0.80835527168997789, 0.81075662651004943, + 0.81314441484925348, 0.81551859675246186, 0.81787913249222477, 0.82022598256943469, + 0.82255910771398810, 0.82487846888544247, 0.82718402727366902, 0.82947574429950277, + 0.83175358161538759, 0.83401750110601802, 0.83626746488897752, 0.83850343531537153, + 0.84072537497045807, 0.84293324667427361, 0.84512701348225505, 0.84730663868585832, + 0.84947208581317246, 0.85162331862952945, 0.85376030113811130, 0.85588299758055186, + 0.85799137243753509, 0.86008539042939003, 0.86216501651668065, 0.86423021590079208, + 0.86628095402451299, 0.86831719657261430, 0.87033890947242287, 0.87234605889439154, + 0.87433861125266565, 0.87631653320564518, 0.87827979165654146, 0.88022835375393260, + 0.88216218689231218, 0.88408125871263499, 0.88598553710285866, 0.88787499019848082, + 0.88974958638307289, 0.89160929428880775, 0.89345408279698646, 0.89528392103855758, + 0.89709877839463381, 0.89889862449700531, 0.90068342922864686, 0.90245316272422227, + 0.90420779537058393, 0.90594729780726846, 0.90767164092698804, 0.90938079587611731, + 0.91107473405517625, 0.91275342711930896, 0.91441684697875725, 0.91606496579933161, + 0.91769775600287662, 0.91931519026773167, 0.92091724152918941, 0.92250388297994779, + 0.92407508807055883, 0.92563083050987272, 0.92717108426547823, 0.92869582356413782, + 0.93020502289221907, 0.93169865699612153, 0.93317670088269977, 0.93463912981968078, + 0.93608591933607832, 0.93751704522260249, 0.93893248353206460, 0.94033221057977767, + 0.94171620294395342, 0.94308443746609349, 0.94443689125137731, 0.94577354166904526, + 0.94709436635277722, 0.94839934320106645, 0.94968845037759042, 0.95096166631157508, + 0.95221896969815656, 0.95346033949873732, 0.95468575494133834, 0.95589519552094671, + 0.95708864099985846, 0.95826607140801767, 0.95942746704335025, 0.96057280847209370, + 0.96170207652912243, 0.96281525231826859, 0.96391231721263748, 0.96499325285492032, + 0.96605804115770066, 0.96710666430375736, 0.96813910474636233, 0.96915534520957514, + 0.97015536868853081, 0.97113915844972509, 0.97210669803129457, 0.97305797124329163, + 0.97399296216795583, 0.97491165515998002, 0.97581403484677187, 0.97670008612871184, + 0.97756979417940515, 0.97842314444593015, 0.97926012264908202, 0.98008071478361125, + 0.98088490711845822, 0.98167268619698311, 0.98244403883719111, 0.98319895213195230, + 0.98393741344921892, 0.98465941043223515, 0.98536493099974543, 0.98605396334619544, + 0.98672649594193018, 0.98738251753338702, 0.98802201714328353, 0.98864498407080170, + 0.98925140789176635, 0.98984127845882053, 0.99041458590159415, 0.99097132062686999, + 0.99151147331874390, 0.99203503493878087, 0.99254199672616605, 0.99303235019785141, + 0.99350608714869759, 0.99396319965161162, 0.99440368005767910, 0.99482752099629224, + 0.99523471537527364, 0.99562525638099431, 0.99599913747848812, 0.99635635241156106, + 0.99669689520289606, 0.99702076015415242, 0.99732794184606210, 0.99761843513851955, + 0.99789223517066816, 0.99814933736098155, 0.99838973740734016, 0.99861343128710323, + 0.99882041525717624, 0.99901068585407338, 0.99918423989397542, 0.99934107447278342, + 0.99948118696616695, 0.99960457502960798, 0.99971123659844041, 0.99980116988788426, + 0.99987437339307572, 0.99993084588909253, 0.99997058643097414, 0.99999359435373747, +}; + +const FLOAT64 iusace_pre_post_twid_cos_256[64] = { + 0.99999529380957619, 0.99961882249517864, 0.99864021818026527, 0.99706007033948307, + 0.99487933079480573, 0.99209931314219191, 0.98872169196032389, 0.98474850180190432, + 0.98018213596811754, 0.97502534506699434, 0.96928123535654864, 0.96295326687368399, + 0.95604525134999652, 0.94856134991573038, 0.94050607059326841, 0.93188426558166815, + 0.92270112833387863, 0.91296219042839821, 0.90267331823725883, 0.89184070939234283, + 0.88047088905216098, 0.86857070597134112, 0.85614732837519469, 0.84320823964184566, + 0.82976123379452327, 0.81581441080673400, 0.80137617172314046, 0.78645521359908599, + 0.77106052426181404, 0.75520137689653677, 0.73888732446061534, 0.72212819392921557, + 0.70493408037590510, 0.68731534089175927, 0.66928258834663623, 0.65084668499638110, + 0.63201873593980917, 0.61281008242940982, 0.59323229503979991, 0.57329716669804232, + 0.55301670558002758, 0.53240312787719801, 0.51146885043797041, 0.49022648328829110, + 0.46868882203582785, 0.44686884016237405, 0.42477968120910869, 0.40243465085941826, + 0.37984720892405099, 0.35703096123342981, 0.33399965144200916, 0.31076715274961120, + 0.28734745954472918, 0.26375467897483096, 0.24000302244874105, 0.21610679707621905, + 0.19208039704989191, 0.16793829497473059, 0.14369503315029383, 0.11936521481099070, + 0.09496349532963828, 0.07050457338961309, 0.04600318213091380, 0.02147408027546862}; +const FLOAT64 iusace_pre_post_twid_sin_256[64] = { + 0.00306795676296598, 0.02760814577896576, 0.05213170468028335, 0.07662386139203153, + 0.10106986275482789, 0.12545498341154632, 0.14976453467732162, 0.17398387338746396, + 0.19809841071795375, 0.22209362097320373, 0.24595505033579484, 0.26966832557291537, + 0.29321916269425891, 0.31659337555616612, 0.33977688440682713, 0.36275572436739750, + 0.38551605384391918, 0.40804416286497902, 0.43032648134008300, 0.45234958723377128, + 0.47410021465055047, 0.49556526182577304, 0.51673179901765043, 0.53758707629564606, + 0.55811853122055666, 0.57831379641165614, 0.59816070699634294, 0.61764730793780453, + 0.63676186123628487, 0.65549285299961613, 0.67382900037875693, 0.69175925836415875, + 0.70927282643886658, 0.72635915508434690, 0.74300795213512272, 0.75920918897838907, + 0.77495310659487493, 0.79023022143731114, 0.80503133114296466, 0.81934752007679812, + 0.83317016470191441, 0.84649093877405335, 0.85930181835700969, 0.87159508665595231, + 0.88336333866573280, 0.89459948563138392, 0.90529675931812004, 0.91544871608826917, + 0.92504924078267903, 0.93409255040426042, 0.94257319760144842, 0.95048607394948326, + 0.95782641302753446, 0.96458979328981431, 0.97077214072895190, 0.97636973133002281, + 0.98137919331375634, 0.98579750916756914, 0.98962201746320266, 0.99285041445986688, + 0.99548075549192871, 0.99751145614030523, 0.99894129318685865, 0.99976940535121717}; + +const FLOAT64 iexheaac_pre_post_twid_cos_192[48] = { + 0.99999163344435060, 0.99932238458834954, 0.99758303629263489, 0.99477545109492771, + 0.99090263542778001, 0.98596873639921179, 0.97997903735188330, 0.97293995220556018, + 0.96485901858892686, 0.95574488976810545, 0.94560732538052128, 0.93445718098403896, + 0.92230639643255874, 0.90916798309052238, 0.89505600990001788, 0.87998558831540419, + 0.86397285612158681, 0.84703496015327406, 0.82919003793371693, 0.81045719825259477, + 0.79085650070384450, 0.77040893420534529, 0.74913639452345926, 0.72706166082649715, + 0.70420837129221303, 0.68060099779545313, 0.65626481970305750, 0.63122589680408292, + 0.60551104140432555, 0.57914778961503477, 0.55216437186655387, 0.52458968267846906, + 0.49645324971863308, 0.46778520218420061, 0.43861623853852771, 0.40897759363848890, + 0.37890100528741033, 0.34841868024943451, 0.31756325976171151, 0.28636778458134332, + 0.25486565960451463, 0.22309061809569275, 0.19107668556520332, 0.15885814333386139, + 0.12646949182367517, 0.09394541361392904, 0.06132073630220865, 0.02863039521013911, +}; + +const FLOAT64 iexheaac_pre_post_twid_sin_192[48] = { + 0.00409060402623479, 0.03680722294135883, 0.06948442776023686, 0.10208722691347411, + 0.13458070850712620, 0.16693007770722965, 0.19910069399898173, 0.23105810828067111, + 0.26276809975263904, 0.29419671256176855, 0.32531029216226293, 0.35607552135377557, + 0.38645945595830333, 0.41642956009763721, 0.44595374103359531, 0.47500038353373153, + 0.50353838372571758, 0.53153718240414893, 0.55896679775410718, 0.58579785745643886, + 0.61200163014036979, 0.63755005614977711, 0.66241577759017178, 0.68657216762421680, + 0.70999335898441229, 0.73265427167241282, 0.75453063981531809, 0.77559903765017746, + 0.79583690460888346, 0.81522256947659355, 0.83373527359780930, 0.85135519310526508, + 0.86806346014782154, 0.88384218309463292, 0.89867446569395382, 0.91254442516606882, + 0.92543720921097061, 0.93733901191257496, 0.94823708852244104, 0.95811976910716823, + 0.96697647104485207, 0.97479771035722163, 0.98157511186532043, 0.98730141815785843, + 0.99197049736262888, 0.99557734971267187, 0.99811811290014918, 0.99959006621220048, +}; + +const FLOAT64 iusace_kbd_win1024[1024] = { + 0.00029256153896361, 0.00042998567353047, 0.00054674074589540, 0.00065482304299792, + 0.00075870195068747, 0.00086059331713336, 0.00096177541439010, 0.0010630609410878, + 0.0011650036308132, 0.0012680012194148, 0.0013723517232956, 0.0014782864109136, + 0.0015859901976719, 0.0016956148252373, 0.0018072876903517, 0.0019211179405514, + 0.0020372007924215, 0.0021556206591754, 0.0022764534599614, 0.0023997683540995, + 0.0025256290631156, 0.0026540948920831, 0.0027852215281403, 0.0029190616715331, + 0.0030556655443223, 0.0031950812943391, 0.0033373553240392, 0.0034825325586930, + 0.0036306566699199, 0.0037817702604646, 0.0039359150179719, 0.0040931318437260, + 0.0042534609610026, 0.0044169420066964, 0.0045836141091341, 0.0047535159544086, + 0.0049266858431214, 0.0051031617390698, 0.0052829813111335, 0.0054661819693975, + 0.0056528008963682, 0.0058428750739943, 0.0060364413070882, 0.0062335362436492, + 0.0064341963925079, 0.0066384581386503, 0.0068463577565218, 0.0070579314215715, + 0.0072732152202559, 0.0074922451586909, 0.0077150571701162, 0.0079416871213115, + 0.0081721708180857, 0.0084065440099458, 0.0086448423940363, 0.0088871016184291, + 0.0091333572848345, 0.0093836449507939, 0.0096380001314086, 0.0098964583006517, + 0.010159054892306, 0.010425825300561, 0.010696804880310, 0.010972028947167, + 0.011251532777236, 0.011535351606646, 0.011823520630897, 0.012116075003993, + 0.012413049837429, 0.012714480198999, 0.013020401111478, 0.013330847551161, + 0.013645854446288, 0.013965456675352, 0.014289689065314, 0.014618586389712, + 0.014952183366697, 0.015290514656976, 0.015633614861688, 0.015981518520214, + 0.016334260107915, 0.016691874033817, 0.017054394638241, 0.017421856190380, + 0.017794292885832, 0.018171738844085, 0.018554228105962, 0.018941794631032, + 0.019334472294980, 0.019732294886947, 0.020135296106839, 0.020543509562604, + 0.020956968767488, 0.021375707137257, 0.021799757987407, 0.022229154530343, + 0.022663929872540, 0.023104117011689, 0.023549748833816, 0.024000858110398, + 0.024457477495451, 0.024919639522613, 0.025387376602207, 0.025860721018295, + 0.026339704925726, 0.026824360347160, 0.027314719170100, 0.027810813143900, + 0.028312673876775, 0.028820332832801, 0.029333821328905, 0.029853170531859, + 0.030378411455255, 0.030909574956490, 0.031446691733739, 0.031989792322926, + 0.032538907094693, 0.033094066251369, 0.033655299823935, 0.034222637668991, + 0.034796109465717, 0.035375744712844, 0.035961572725616, 0.036553622632758, + 0.037151923373446, 0.037756503694277, 0.038367392146243, 0.038984617081711, + 0.039608206651398, 0.040238188801359, 0.040874591269976, 0.041517441584950, + 0.042166767060301, 0.042822594793376, 0.043484951661852, 0.044153864320760, + 0.044829359199509, 0.045511462498913, 0.046200200188234, 0.046895598002228, + 0.047597681438201, 0.048306475753074, 0.049022005960455, 0.049744296827725, + 0.050473372873129, 0.051209258362879, 0.051951977308273, 0.052701553462813, + 0.053458010319350, 0.054221371107223, 0.054991658789428, 0.055768896059787, + 0.056553105340134, 0.057344308777513, 0.058142528241393, 0.058947785320893, + 0.059760101322019, 0.060579497264926, 0.061405993881180, 0.062239611611049, + 0.063080370600799, 0.063928290700012, 0.064783391458919, 0.065645692125747, + 0.066515211644086, 0.067391968650269, 0.068275981470777, 0.069167268119652, + 0.070065846295935, 0.070971733381121, 0.071884946436630, 0.072805502201299, + 0.073733417088896, 0.074668707185649, 0.075611388247794, 0.076561475699152, + 0.077518984628715, 0.078483929788261, 0.079456325589986, 0.080436186104162, + 0.081423525056808, 0.082418355827392, 0.083420691446553, 0.084430544593841, + 0.085447927595483, 0.086472852422178, 0.087505330686900, 0.088545373642744, + 0.089592992180780, 0.090648196827937, 0.091710997744919, 0.092781404724131, + 0.093859427187640, 0.094945074185163, 0.096038354392069, 0.097139276107423, + 0.098247847252041, 0.099364075366580, 0.10048796760965, 0.10161953075597, + 0.10275877119451, 0.10390569492671, 0.10506030756469, 0.10622261432949, + 0.10739262004941, 0.10857032915821, 0.10975574569357, 0.11094887329534, + 0.11214971520402, 0.11335827425914, 0.11457455289772, 0.11579855315274, + 0.11703027665170, 0.11826972461510, 0.11951689785504, 0.12077179677383, + 0.12203442136263, 0.12330477120008, 0.12458284545102, 0.12586864286523, + 0.12716216177615, 0.12846340009971, 0.12977235533312, 0.13108902455375, + 0.13241340441801, 0.13374549116025, 0.13508528059173, 0.13643276809961, + 0.13778794864595, 0.13915081676677, 0.14052136657114, 0.14189959174027, + 0.14328548552671, 0.14467904075349, 0.14608024981336, 0.14748910466804, + 0.14890559684750, 0.15032971744929, 0.15176145713790, 0.15320080614414, + 0.15464775426459, 0.15610229086100, 0.15756440485987, 0.15903408475193, + 0.16051131859170, 0.16199609399712, 0.16348839814917, 0.16498821779156, + 0.16649553923042, 0.16801034833404, 0.16953263053270, 0.17106237081842, + 0.17259955374484, 0.17414416342714, 0.17569618354193, 0.17725559732720, + 0.17882238758238, 0.18039653666830, 0.18197802650733, 0.18356683858343, + 0.18516295394233, 0.18676635319174, 0.18837701650148, 0.18999492360384, + 0.19162005379380, 0.19325238592940, 0.19489189843209, 0.19653856928714, + 0.19819237604409, 0.19985329581721, 0.20152130528605, 0.20319638069594, + 0.20487849785865, 0.20656763215298, 0.20826375852540, 0.20996685149083, + 0.21167688513330, 0.21339383310678, 0.21511766863598, 0.21684836451719, + 0.21858589311922, 0.22033022638425, 0.22208133582887, 0.22383919254503, + 0.22560376720111, 0.22737503004300, 0.22915295089517, 0.23093749916189, + 0.23272864382838, 0.23452635346201, 0.23633059621364, 0.23814133981883, + 0.23995855159925, 0.24178219846403, 0.24361224691114, 0.24544866302890, + 0.24729141249740, 0.24914046059007, 0.25099577217522, 0.25285731171763, + 0.25472504328019, 0.25659893052556, 0.25847893671788, 0.26036502472451, + 0.26225715701781, 0.26415529567692, 0.26605940238966, 0.26796943845439, + 0.26988536478190, 0.27180714189742, 0.27373472994256, 0.27566808867736, + 0.27760717748238, 0.27955195536071, 0.28150238094021, 0.28345841247557, + 0.28542000785059, 0.28738712458038, 0.28935971981364, 0.29133775033492, + 0.29332117256704, 0.29530994257338, 0.29730401606034, 0.29930334837974, + 0.30130789453132, 0.30331760916521, 0.30533244658452, 0.30735236074785, + 0.30937730527195, 0.31140723343430, 0.31344209817583, 0.31548185210356, + 0.31752644749341, 0.31957583629288, 0.32162997012390, 0.32368880028565, + 0.32575227775738, 0.32782035320134, 0.32989297696566, 0.33197009908736, + 0.33405166929523, 0.33613763701295, 0.33822795136203, 0.34032256116495, + 0.34242141494820, 0.34452446094547, 0.34663164710072, 0.34874292107143, + 0.35085823023181, 0.35297752167598, 0.35510074222129, 0.35722783841160, + 0.35935875652060, 0.36149344255514, 0.36363184225864, 0.36577390111444, + 0.36791956434930, 0.37006877693676, 0.37222148360070, 0.37437762881878, + 0.37653715682603, 0.37870001161834, 0.38086613695607, 0.38303547636766, + 0.38520797315322, 0.38738357038821, 0.38956221092708, 0.39174383740701, + 0.39392839225157, 0.39611581767449, 0.39830605568342, 0.40049904808370, + 0.40269473648218, 0.40489306229101, 0.40709396673153, 0.40929739083810, + 0.41150327546197, 0.41371156127524, 0.41592218877472, 0.41813509828594, + 0.42035022996702, 0.42256752381274, 0.42478691965848, 0.42700835718423, + 0.42923177591866, 0.43145711524314, 0.43368431439580, 0.43591331247564, + 0.43814404844658, 0.44037646114161, 0.44261048926688, 0.44484607140589, + 0.44708314602359, 0.44932165147057, 0.45156152598727, 0.45380270770813, + 0.45604513466581, 0.45828874479543, 0.46053347593880, 0.46277926584861, + 0.46502605219277, 0.46727377255861, 0.46952236445718, 0.47177176532752, + 0.47402191254100, 0.47627274340557, 0.47852419517009, 0.48077620502869, + 0.48302871012505, 0.48528164755674, 0.48753495437962, 0.48978856761212, + 0.49204242423966, 0.49429646121898, 0.49655061548250, 0.49880482394273, + 0.50105902349665, 0.50331315103004, 0.50556714342194, 0.50782093754901, + 0.51007447028990, 0.51232767852971, 0.51458049916433, 0.51683286910489, + 0.51908472528213, 0.52133600465083, 0.52358664419420, 0.52583658092832, + 0.52808575190648, 0.53033409422367, 0.53258154502092, 0.53482804148974, + 0.53707352087652, 0.53931792048690, 0.54156117769021, 0.54380322992385, + 0.54604401469766, 0.54828346959835, 0.55052153229384, 0.55275814053768, + 0.55499323217338, 0.55722674513883, 0.55945861747062, 0.56168878730842, + 0.56391719289930, 0.56614377260214, 0.56836846489188, 0.57059120836390, + 0.57281194173835, 0.57503060386439, 0.57724713372458, 0.57946147043912, + 0.58167355327012, 0.58388332162591, 0.58609071506528, 0.58829567330173, + 0.59049813620770, 0.59269804381879, 0.59489533633802, 0.59708995413996, + 0.59928183777495, 0.60147092797329, 0.60365716564937, 0.60584049190582, + 0.60802084803764, 0.61019817553632, 0.61237241609393, 0.61454351160718, + 0.61671140418155, 0.61887603613527, 0.62103735000336, 0.62319528854167, + 0.62534979473088, 0.62750081178042, 0.62964828313250, 0.63179215246597, + 0.63393236370030, 0.63606886099946, 0.63820158877577, 0.64033049169379, + 0.64245551467413, 0.64457660289729, 0.64669370180740, 0.64880675711607, + 0.65091571480603, 0.65302052113494, 0.65512112263906, 0.65721746613689, + 0.65930949873289, 0.66139716782102, 0.66348042108842, 0.66555920651892, + 0.66763347239664, 0.66970316730947, 0.67176824015260, 0.67382864013196, + 0.67588431676768, 0.67793521989751, 0.67998129968017, 0.68202250659876, + 0.68405879146403, 0.68609010541774, 0.68811639993588, 0.69013762683195, + 0.69215373826012, 0.69416468671849, 0.69617042505214, 0.69817090645634, + 0.70016608447958, 0.70215591302664, 0.70414034636163, 0.70611933911096, + 0.70809284626630, 0.71006082318751, 0.71202322560554, 0.71398000962530, + 0.71593113172842, 0.71787654877613, 0.71981621801195, 0.72175009706445, + 0.72367814394990, 0.72560031707496, 0.72751657523927, 0.72942687763803, + 0.73133118386457, 0.73322945391280, 0.73512164817975, 0.73700772746796, + 0.73888765298787, 0.74076138636020, 0.74262888961827, 0.74449012521027, + 0.74634505600152, 0.74819364527663, 0.75003585674175, 0.75187165452661, + 0.75370100318668, 0.75552386770515, 0.75734021349500, 0.75915000640095, + 0.76095321270137, 0.76274979911019, 0.76453973277875, 0.76632298129757, + 0.76809951269819, 0.76986929545481, 0.77163229848604, 0.77338849115651, + 0.77513784327849, 0.77688032511340, 0.77861590737340, 0.78034456122283, + 0.78206625827961, 0.78378097061667, 0.78548867076330, 0.78718933170643, + 0.78888292689189, 0.79056943022564, 0.79224881607494, 0.79392105926949, + 0.79558613510249, 0.79724401933170, 0.79889468818046, 0.80053811833858, + 0.80217428696334, 0.80380317168028, 0.80542475058405, 0.80703900223920, + 0.80864590568089, 0.81024544041560, 0.81183758642175, 0.81342232415032, + 0.81499963452540, 0.81656949894467, 0.81813189927991, 0.81968681787738, + 0.82123423755821, 0.82277414161874, 0.82430651383076, 0.82583133844180, + 0.82734860017528, 0.82885828423070, 0.83036037628369, 0.83185486248609, + 0.83334172946597, 0.83482096432759, 0.83629255465130, 0.83775648849344, + 0.83921275438615, 0.84066134133716, 0.84210223882952, 0.84353543682130, + 0.84496092574524, 0.84637869650833, 0.84778874049138, 0.84919104954855, + 0.85058561600677, 0.85197243266520, 0.85335149279457, 0.85472279013653, + 0.85608631890295, 0.85744207377513, 0.85879004990298, 0.86013024290422, + 0.86146264886346, 0.86278726433124, 0.86410408632306, 0.86541311231838, + 0.86671434025950, 0.86800776855046, 0.86929339605590, 0.87057122209981, + 0.87184124646433, 0.87310346938840, 0.87435789156650, 0.87560451414719, + 0.87684333873173, 0.87807436737261, 0.87929760257204, 0.88051304728038, + 0.88172070489456, 0.88292057925645, 0.88411267465117, 0.88529699580537, + 0.88647354788545, 0.88764233649580, 0.88880336767692, 0.88995664790351, + 0.89110218408260, 0.89223998355154, 0.89337005407600, 0.89449240384793, + 0.89560704148345, 0.89671397602074, 0.89781321691786, 0.89890477405053, + 0.89998865770993, 0.90106487860034, 0.90213344783689, 0.90319437694315, + 0.90424767784873, 0.90529336288690, 0.90633144479201, 0.90736193669708, + 0.90838485213119, 0.90940020501694, 0.91040800966776, 0.91140828078533, + 0.91240103345685, 0.91338628315231, 0.91436404572173, 0.91533433739238, + 0.91629717476594, 0.91725257481564, 0.91820055488334, 0.91914113267664, + 0.92007432626589, 0.92100015408120, 0.92191863490944, 0.92282978789113, + 0.92373363251740, 0.92463018862687, 0.92551947640245, 0.92640151636824, + 0.92727632938624, 0.92814393665320, 0.92900435969727, 0.92985762037477, + 0.93070374086684, 0.93154274367610, 0.93237465162328, 0.93319948784382, + 0.93401727578443, 0.93482803919967, 0.93563180214841, 0.93642858899043, + 0.93721842438279, 0.93800133327637, 0.93877734091223, 0.93954647281807, + 0.94030875480458, 0.94106421296182, 0.94181287365556, 0.94255476352362, + 0.94328990947213, 0.94401833867184, 0.94474007855439, 0.94545515680855, + 0.94616360137644, 0.94686544044975, 0.94756070246592, 0.94824941610434, + 0.94893161028248, 0.94960731415209, 0.95027655709525, 0.95093936872056, + 0.95159577885924, 0.95224581756115, 0.95288951509097, 0.95352690192417, + 0.95415800874314, 0.95478286643320, 0.95540150607863, 0.95601395895871, + 0.95662025654373, 0.95722043049100, 0.95781451264084, 0.95840253501260, + 0.95898452980058, 0.95956052937008, 0.96013056625336, 0.96069467314557, + 0.96125288290073, 0.96180522852773, 0.96235174318622, 0.96289246018262, + 0.96342741296604, 0.96395663512424, 0.96448016037959, 0.96499802258499, + 0.96551025571985, 0.96601689388602, 0.96651797130376, 0.96701352230768, + 0.96750358134269, 0.96798818295998, 0.96846736181297, 0.96894115265327, + 0.96940959032667, 0.96987270976912, 0.97033054600270, 0.97078313413161, + 0.97123050933818, 0.97167270687887, 0.97210976208030, 0.97254171033525, + 0.97296858709871, 0.97339042788392, 0.97380726825843, 0.97421914384017, + 0.97462609029350, 0.97502814332534, 0.97542533868127, 0.97581771214160, + 0.97620529951759, 0.97658813664749, 0.97696625939282, 0.97733970363445, + 0.97770850526884, 0.97807270020427, 0.97843232435704, 0.97878741364771, + 0.97913800399743, 0.97948413132414, 0.97982583153895, 0.98016314054243, + 0.98049609422096, 0.98082472844313, 0.98114907905608, 0.98146918188197, + 0.98178507271438, 0.98209678731477, 0.98240436140902, 0.98270783068385, + 0.98300723078342, 0.98330259730589, 0.98359396579995, 0.98388137176152, + 0.98416485063031, 0.98444443778651, 0.98472016854752, 0.98499207816463, + 0.98526020181980, 0.98552457462240, 0.98578523160609, 0.98604220772560, + 0.98629553785362, 0.98654525677772, 0.98679139919726, 0.98703399972035, + 0.98727309286089, 0.98750871303556, 0.98774089456089, 0.98796967165036, + 0.98819507841154, 0.98841714884323, 0.98863591683269, 0.98885141615285, + 0.98906368045957, 0.98927274328896, 0.98947863805473, 0.98968139804554, + 0.98988105642241, 0.99007764621618, 0.99027120032501, 0.99046175151186, + 0.99064933240208, 0.99083397548099, 0.99101571309153, 0.99119457743191, + 0.99137060055337, 0.99154381435784, 0.99171425059582, 0.99188194086414, + 0.99204691660388, 0.99220920909823, 0.99236884947045, 0.99252586868186, + 0.99268029752989, 0.99283216664606, 0.99298150649419, 0.99312834736847, + 0.99327271939167, 0.99341465251338, 0.99355417650825, 0.99369132097430, + 0.99382611533130, 0.99395858881910, 0.99408877049612, 0.99421668923778, + 0.99434237373503, 0.99446585249289, 0.99458715382906, 0.99470630587254, + 0.99482333656229, 0.99493827364600, 0.99505114467878, 0.99516197702200, + 0.99527079784214, 0.99537763410962, 0.99548251259777, 0.99558545988178, + 0.99568650233767, 0.99578566614138, 0.99588297726783, 0.99597846149005, + 0.99607214437834, 0.99616405129947, 0.99625420741595, 0.99634263768527, + 0.99642936685928, 0.99651441948352, 0.99659781989663, 0.99667959222978, + 0.99675976040620, 0.99683834814063, 0.99691537893895, 0.99699087609774, + 0.99706486270391, 0.99713736163442, 0.99720839555593, 0.99727798692461, + 0.99734615798589, 0.99741293077431, 0.99747832711337, 0.99754236861541, + 0.99760507668158, 0.99766647250181, 0.99772657705478, 0.99778541110799, + 0.99784299521785, 0.99789934972976, 0.99795449477828, 0.99800845028730, + 0.99806123597027, 0.99811287133042, 0.99816337566108, 0.99821276804596, + 0.99826106735952, 0.99830829226732, 0.99835446122649, 0.99839959248609, + 0.99844370408765, 0.99848681386566, 0.99852893944805, 0.99857009825685, + 0.99861030750869, 0.99864958421549, 0.99868794518504, 0.99872540702178, + 0.99876198612738, 0.99879769870160, 0.99883256074295, 0.99886658804953, + 0.99889979621983, 0.99893220065356, 0.99896381655254, 0.99899465892154, + 0.99902474256924, 0.99905408210916, 0.99908269196056, 0.99911058634952, + 0.99913777930986, 0.99916428468421, 0.99919011612505, 0.99921528709576, + 0.99923981087174, 0.99926370054150, 0.99928696900779, 0.99930962898876, + 0.99933169301910, 0.99935317345126, 0.99937408245662, 0.99939443202674, + 0.99941423397457, 0.99943349993572, 0.99945224136972, 0.99947046956130, + 0.99948819562171, 0.99950543049000, 0.99952218493439, 0.99953846955355, + 0.99955429477803, 0.99956967087154, 0.99958460793242, 0.99959911589494, + 0.99961320453077, 0.99962688345035, 0.99964016210433, 0.99965304978499, + 0.99966555562769, 0.99967768861231, 0.99968945756473, 0.99970087115825, + 0.99971193791510, 0.99972266620792, 0.99973306426121, 0.99974314015288, + 0.99975290181568, 0.99976235703876, 0.99977151346914, 0.99978037861326, + 0.99978895983845, 0.99979726437448, 0.99980529931507, 0.99981307161943, + 0.99982058811377, 0.99982785549283, 0.99983488032144, 0.99984166903600, + 0.99984822794606, 0.99985456323584, 0.99986068096572, 0.99986658707386, + 0.99987228737764, 0.99987778757524, 0.99988309324717, 0.99988820985777, + 0.99989314275675, 0.99989789718072, 0.99990247825468, 0.99990689099357, + 0.99991114030376, 0.99991523098456, 0.99991916772971, 0.99992295512891, + 0.99992659766930, 0.99993009973692, 0.99993346561824, 0.99993669950161, + 0.99993980547870, 0.99994278754604, 0.99994564960642, 0.99994839547033, + 0.99995102885747, 0.99995355339809, 0.99995597263451, 0.99995829002249, + 0.99996050893264, 0.99996263265183, 0.99996466438460, 0.99996660725452, + 0.99996846430558, 0.99997023850356, 0.99997193273736, 0.99997354982037, + 0.99997509249183, 0.99997656341810, 0.99997796519400, 0.99997930034415, + 0.99998057132421, 0.99998178052220, 0.99998293025975, 0.99998402279338, + 0.99998506031574, 0.99998604495686, 0.99998697878536, 0.99998786380966, + 0.99998870197921, 0.99998949518567, 0.99999024526408, 0.99999095399401, + 0.99999162310077, 0.99999225425649, 0.99999284908128, 0.99999340914435, + 0.99999393596510, 0.99999443101421, 0.99999489571473, 0.99999533144314, + 0.99999573953040, 0.99999612126300, 0.99999647788395, 0.99999681059383, + 0.99999712055178, 0.99999740887647, 0.99999767664709, 0.99999792490431, + 0.99999815465123, 0.99999836685427, 0.99999856244415, 0.99999874231676, + 0.99999890733405, 0.99999905832493, 0.99999919608613, 0.99999932138304, + 0.99999943495056, 0.99999953749392, 0.99999962968950, 0.99999971218563, + 0.99999978560337, 0.99999985053727, 0.99999990755616, 0.99999995720387}; + +const FLOAT64 iusace_kbd_win128[128] = { + 4.3795702929468881e-005, 0.00011867384265436617, 0.0002307165763996192, + 0.00038947282760568383, 0.00060581272288302553, 0.00089199695169487453, + 0.0012617254423430522, 0.0017301724373162003, 0.0023140071937421476, + 0.0030313989666022221, 0.0039020049735530842, 0.0049469401815512024, + 0.0061887279335368318, 0.0076512306364647726, 0.0093595599562652423, + 0.011339966208377799, 0.013619706891715299, 0.016226894586323766, + 0.019190324717288168, 0.022539283975960878, 0.026303340480472455, + 0.030512117046644357, 0.03519504922365594, 0.040381130021856941, + 0.046098643518702249, 0.052374889768730587, 0.059235903660769147, + 0.066706170556282418, 0.074808341703430481, 0.083562952548726227, + 0.092988147159339674, 0.1030994120216919, 0.11390932249409955, + 0.12542730516149531, 0.13765941926783826, 0.15060816028651081, + 0.16427228853114245, 0.17864668550988483, 0.19372224048676889, + 0.20948576943658073, 0.22591996826744942, 0.24300340184133981, + 0.26071052995068139, 0.27901177101369551, 0.29787360383626599, + 0.3172587073594233, 0.33712613787396362, 0.35743154274286698, + 0.37812740923363009, 0.39916334663203618, 0.42048639939189658, + 0.4420413886774246, 0.4637712792815169, 0.4856175685594023, + 0.50752069370766872, 0.52942045344797806, 0.55125643994680196, + 0.57296847662071559, 0.59449705734411495, 0.61578378249506627, + 0.63677178724712891, 0.65740615754163356, 0.67763432925662526, + 0.69740646622548552, 0.71667581294953808, 0.73539901809352737, + 0.75353642514900732, 0.77105232699609816, 0.78791518148597028, + 0.80409778560147072, 0.81957740622770781, 0.83433586607383625, + 0.84835958382689225, 0.86163956818294229, 0.87417136598406997, + 0.88595496528524853, 0.89699465477567619, 0.90729884157670959, + 0.91687983002436779, 0.92575356460899649, 0.93393934077779084, + 0.94145948779657318, 0.94833902830402828, 0.95460531956280026, + 0.96028768170574896, 0.96541701848104766, 0.97002543610646474, + 0.97414586584250062, 0.97781169577969584, 0.98105641710392333, + 0.98391328975491177, 0.98641503193166202, 0.98859353733226141, + 0.99047962335771556, 0.9921028127769449, 0.99349115056397752, + 0.99467105680259038, 0.9956672157341897, 0.99650250022834352, + 0.99719793020823266, 0.99777266288955657, 0.99824401211201486, + 0.99862749357391212, 0.99893689243401962, 0.99918434952623147, + 0.99938046234161726, 0.99953439696357238, 0.99965400728430465, + 0.99974595807027455, 0.99981584876278362, 0.99986833527824281, + 0.99990724749057802, 0.99993570051598468, 0.99995619835942084, + 0.99997072890647543, 0.9999808496399144, 0.99998776381655818, + 0.99999238714961569, 0.99999540529959718, 0.99999732268176988, + 0.99999850325054862, 0.99999920402413744, 0.9999996021706401, + 0.99999981649545566, 0.99999992415545547, 0.99999997338493041, + 0.99999999295825959, 0.99999999904096815}; + +const FLOAT64 iexheaac_kbd_win_768[768] = { + 0.00033799977973104, 0.00050299987196922, 0.00064699957147241, 0.00078399991616607, + 0.00091799953952432, 0.00105199962854385, 0.00118699949234724, 0.00132499961182475, + 0.00146499974653125, 0.00160799967125058, 0.00175499962642789, 0.00190499983727932, + 0.00205999985337257, 0.00221799965947866, 0.00238199951127172, 0.00254899961873889, + 0.00272099953144789, 0.00289899948984385, 0.00308099947869778, 0.00326799973845482, + 0.00345999980345368, 0.00365699967369437, 0.00385999958962202, 0.00406799931079149, + 0.00428199954330921, 0.00450099958106875, 0.00472599966451526, 0.00495699932798743, + 0.00519399950280786, 0.00543599948287010, 0.00568499974906445, 0.00593999959528446, + 0.00620099948719144, 0.00646899966523051, 0.00674299942329526, 0.00702299969270825, + 0.00730999931693077, 0.00760399969294667, 0.00790399918332696, 0.00821099942550063, + 0.00852599972859025, 0.00884699961170554, 0.00917499931529164, 0.00951099907979369, + 0.00985299935564399, 0.01020399993285537, 0.01056099915876985, 0.01092599937692285, + 0.01129899965599179, 0.01167899975553155, 0.01206699991598725, 0.01246299920603633, + 0.01286699948832393, 0.01327899983152747, 0.01369899930432439, 0.01412699976935983, + 0.01456399960443377, 0.01500799925997853, 0.01546099921688437, 0.01592300040647388, + 0.01639400003477931, 0.01687299972400069, 0.01735999947413802, 0.01785699976608157, + 0.01836200011894107, 0.01887699915096164, 0.01940000010654330, 0.01993299974128604, + 0.02047499967738986, 0.02102599991485476, 0.02158699883148074, 0.02215699991211295, + 0.02273699967190623, 0.02332599973306060, 0.02392500033602118, 0.02453399961814284, + 0.02515299944207072, 0.02578099956735969, 0.02641999861225486, 0.02706900006160140, + 0.02772699994966388, 0.02839699899777770, 0.02907600020989776, 0.02976600034162402, + 0.03046599915251136, 0.03117699874565005, 0.03189900098368526, 0.03263099817559123, + 0.03337399987503886, 0.03412700025364757, 0.03489199979230762, 0.03566800011321902, + 0.03645399911329150, 0.03725200099870563, 0.03806099994108081, 0.03888099966570735, + 0.03971200017258525, 0.04055499983951449, 0.04140900028869510, 0.04227499989792705, + 0.04315299866721034, 0.04404199821874499, 0.04494199855253100, 0.04585500014945865, + 0.04677899880334735, 0.04771500034257770, 0.04866300104185939, 0.04962300090119243, + 0.05059499992057681, 0.05157899810001254, 0.05257600126788020, 0.05358399776741862, + 0.05460499925538898, 0.05563799990341067, 0.05668399808928370, 0.05774199916049838, + 0.05881299776956439, 0.05989599926397204, 0.06099099991843104, 0.06210000021383166, + 0.06322099966928363, 0.06435400201007724, 0.06550099654123187, 0.06666000140830874, + 0.06783299846574664, 0.06901799840852618, 0.07021599961444736, 0.07142700208351016, + 0.07265099836513400, 0.07388799590989947, 0.07513900054618716, 0.07640200061723590, + 0.07767900032922626, 0.07896900130435824, 0.08027199609205127, 0.08158799959346652, + 0.08291800273582339, 0.08426099969074130, 0.08561799628660083, 0.08698800159618258, + 0.08837100071832538, 0.08976799948140979, 0.09117799950763583, 0.09260199917480350, + 0.09403900010511279, 0.09549000067636371, 0.09695500088855624, 0.09843300236389041, + 0.09992399765178561, 0.10142999840900302, 0.10294900042936206, 0.10448099626228213, + 0.10602799756452441, 0.10758800012990832, 0.10916099650785327, 0.11074899835512042, + 0.11235000146552920, 0.11396499676629901, 0.11559300078079104, 0.11723600281402469, + 0.11889199865981936, 0.12056100321933627, 0.12224499834701419, 0.12394200218841434, + 0.12565299822017550, 0.12737800134345889, 0.12911599827930331, 0.13086800230666995, + 0.13263399852439761, 0.13441400183364749, 0.13620699895545840, 0.13801400316879153, + 0.13983400119468570, 0.14166900468990207, 0.14351700199767947, 0.14537799311801791, + 0.14725300623103976, 0.14914199663326144, 0.15104399574920535, 0.15296000195667148, + 0.15488900197669864, 0.15683199418708682, 0.15878799511119723, 0.16075800312682986, + 0.16274100495502353, 0.16473700059577823, 0.16674700332805514, 0.16876999987289310, + 0.17080600513145328, 0.17285600258037448, 0.17491899384185672, 0.17699499381706119, + 0.17908400250598788, 0.18118600500747561, 0.18330100132152438, 0.18542900634929538, + 0.18757000518962741, 0.18972399784252048, 0.19189099920913577, 0.19407099438831210, + 0.19626299990341067, 0.19846799923107028, 0.20068599237129092, 0.20291599584743381, + 0.20515899313613772, 0.20741400076076388, 0.20968200219795108, 0.21196199906989932, + 0.21425400627776980, 0.21655899239704013, 0.21887500537559390, 0.22120399726554751, + 0.22354499949142337, 0.22589799715206027, 0.22826300514861941, 0.23063899530097842, + 0.23302699578925967, 0.23542700661346316, 0.23783799959346652, 0.24026100290939212, + 0.24269600166007876, 0.24514199746772647, 0.24759900523349643, 0.25006699515506625, + 0.25254601193591952, 0.25503599597141147, 0.25753799034282565, 0.26004999829456210, + 0.26257199002429843, 0.26510599208995700, 0.26765000773593783, 0.27020499063655734, + 0.27276998711749911, 0.27534499717876315, 0.27792999101802707, 0.28052601171657443, + 0.28313100291416049, 0.28574699116870761, 0.28837200952693820, 0.29100701166316867, + 0.29365199757739902, 0.29630601359531283, 0.29896900011226535, 0.30164200020954013, + 0.30432400060817599, 0.30701500130817294, 0.30971500230953097, 0.31242299033328891, + 0.31514099193736911, 0.31786701036617160, 0.32060199929401278, 0.32334500504657626, + 0.32609599782153964, 0.32885599089786410, 0.33162298751994967, 0.33439800096675754, + 0.33718198491260409, 0.33997300220653415, 0.34277099324390292, 0.34557700110599399, + 0.34839001251384616, 0.35121101094409823, 0.35403799964115024, 0.35687300516292453, + 0.35971400095149875, 0.36256200028583407, 0.36541598988696933, 0.36827701283618808, + 0.37114399624988437, 0.37401801301166415, 0.37689700676128268, 0.37978199077770114, + 0.38267299486324191, 0.38556998921558261, 0.38847199035808444, 0.39138001156970859, + 0.39429199649021029, 0.39721000147983432, 0.40013301325961947, 0.40305998874828219, + 0.40599301410838962, 0.40893000317737460, 0.41187098575755954, 0.41481599165126681, + 0.41776600433513522, 0.42071899725124240, 0.42367699695751071, 0.42663800669834018, + 0.42960199667140841, 0.43257000995799899, 0.43554100347682834, 0.43851599050685763, + 0.44149300409480929, 0.44447299791499972, 0.44745600176975131, 0.45044100238010287, + 0.45342901302501559, 0.45641899062320590, 0.45941099477931857, 0.46240499569103122, + 0.46540000988170505, 0.46839800430461764, 0.47139599872753024, 0.47439700318500400, + 0.47739800764247775, 0.48039999557659030, 0.48340401006862521, 0.48640799475833774, + 0.48941299272701144, 0.49241799069568515, 0.49542298866435885, 0.49842899991199374, + 0.50143402768298984, 0.50444000912830234, 0.50744497729465365, 0.51045000506564975, + 0.51345401955768466, 0.51645702077075839, 0.51946002198383212, 0.52246099663898349, + 0.52546101761981845, 0.52846002532169223, 0.53145801974460483, 0.53445297433063388, + 0.53744697524234653, 0.54043900920078158, 0.54342901660129428, 0.54641699744388461, + 0.54940199805423617, 0.55238497210666537, 0.55536502553150058, 0.55834299279376864, + 0.56131702614948153, 0.56428801966831088, 0.56725597335025668, 0.57022100640460849, + 0.57318198634311557, 0.57613897277042270, 0.57909202529117465, 0.58204197837039828, + 0.58498698426410556, 0.58792799664661288, 0.59086501551792026, 0.59379702759906650, + 0.59672397328540683, 0.59964698506519198, 0.60256397677585483, 0.60547697497531772, + 0.60838401271030307, 0.61128598405048251, 0.61418199492618442, 0.61707198573276401, + 0.61995696974918246, 0.62283599330112338, 0.62570798350498080, 0.62857502652332187, + 0.63143497658893466, 0.63428902579471469, 0.63713598204776645, 0.63997602416202426, + 0.64280897332355380, 0.64563602162525058, 0.64845502329990268, 0.65126699162647128, + 0.65407097293063998, 0.65686798049136996, 0.65965801430866122, 0.66243898821994662, + 0.66521298838779330, 0.66797900153324008, 0.67073601437732577, 0.67348599387332797, + 0.67622601939365268, 0.67895901156589389, 0.68168300343677402, 0.68439799500629306, + 0.68710398627445102, 0.68980097724124789, 0.69248902751132846, 0.69516801787540317, + 0.69783800793811679, 0.70049798442050815, 0.70314902020618320, 0.70578998280689120, + 0.70842099143192172, 0.71104299975559115, 0.71365398121997714, 0.71625602198764682, + 0.71884697629138827, 0.72142797661945224, 0.72399902297183871, 0.72655898286029696, + 0.72910898877307773, 0.73164802743121982, 0.73417597962543368, 0.73669397784397006, + 0.73919999552890658, 0.74169599963352084, 0.74418002320453525, 0.74665397359058261, + 0.74911600304767489, 0.75156599236652255, 0.75400501443073153, 0.75643300963565707, + 0.75884902430698276, 0.76125299884006381, 0.76364600611850619, 0.76602601958438754, + 0.76839500619098544, 0.77075201226398349, 0.77309602452442050, 0.77542900992557406, + 0.77774900151416659, 0.78005701256915927, 0.78235298348590732, 0.78463602019473910, + 0.78690600348636508, 0.78916501952335238, 0.79141002846881747, 0.79364299727603793, + 0.79586297227069736, 0.79807001305744052, 0.80026501370593905, 0.80244600726291537, + 0.80461502028629184, 0.80677097989246249, 0.80891299201175570, 0.81104302359744906, + 0.81315898848697543, 0.81526201916858554, 0.81735199643298984, 0.81942802621051669, + 0.82149201584979892, 0.82354098511859775, 0.82557797385379672, 0.82760101510211825, + 0.82960998965427279, 0.83160597039386630, 0.83358901692554355, 0.83555799676105380, + 0.83751302910968661, 0.83945500804111362, 0.84138297988101840, 0.84329700423404574, + 0.84519797516986728, 0.84708499861881137, 0.84895801497623324, 0.85081702424213290, + 0.85266298009082675, 0.85449498845264316, 0.85631298972293735, 0.85811698390170932, + 0.85990798426792026, 0.86168402386829257, 0.86344701005145907, 0.86519598914310336, + 0.86693102074787021, 0.86865198565647006, 0.87035900307819247, 0.87205201340839267, + 0.87373197032138705, 0.87539797974750400, 0.87704902840778232, 0.87868702365085483, + 0.88031101180240512, 0.88192099286243320, 0.88351798010990024, 0.88510000659152865, + 0.88666897965595126, 0.88822400523349643, 0.88976502371951938, 0.89129298878833652, + 0.89280599309131503, 0.89430600358173251, 0.89579200698062778, 0.89726501656696200, + 0.89872401906177402, 0.90016901446506381, 0.90160000277683139, 0.90301799727603793, + 0.90442299796268344, 0.90581399155780673, 0.90719097806140780, 0.90855497075244784, + 0.90990501595661044, 0.91124200774356723, 0.91256600571796298, 0.91387599660083652, + 0.91517299367114902, 0.91645699692890048, 0.91772800637409091, 0.91898500872775912, + 0.92022901726886630, 0.92146098567172885, 0.92267900658771396, 0.92388397408649325, + 0.92507600737735629, 0.92625498725101352, 0.92742198659107089, 0.92857497883960605, + 0.92971599055454135, 0.93084400845691562, 0.93195998622104526, 0.93306297017261386, + 0.93415301991626620, 0.93523096991702914, 0.93629598570987582, 0.93734997464343905, + 0.93839001609012485, 0.93941897107288241, 0.94043499184772372, 0.94143998576328158, + 0.94243198586627841, 0.94341200543567538, 0.94437998486682773, 0.94533699704334140, + 0.94628101540729403, 0.94721400691196322, 0.94813501788303256, 0.94904500199481845, + 0.94994300557300448, 0.95082998229190707, 0.95170497847720981, 0.95256900740787387, + 0.95342099620029330, 0.95426297141239047, 0.95509302569553256, 0.95591199351474643, + 0.95672100735828280, 0.95751798106357455, 0.95830500079318881, 0.95908099366351962, + 0.95984601927921176, 0.96060097170993686, 0.96134501649066806, 0.96207898808643222, + 0.96280300570651889, 0.96351599646732211, 0.96421897364780307, 0.96491199685260653, + 0.96559500647708774, 0.96626800252124667, 0.96693098498508334, 0.96758502675220370, + 0.96822899533435702, 0.96886300994083285, 0.96948701096698642, 0.97010201169177890, + 0.97070801211521029, 0.97130501223728061, 0.97189199877902865, 0.97246998501941562, + 0.97303897095844150, 0.97359996987506747, 0.97415101481601596, 0.97469401312991977, + 0.97522699786350131, 0.97575300885364413, 0.97627001954242587, 0.97677797032520175, + 0.97727799369022250, 0.97776997042819858, 0.97825300646945834, 0.97872900916263461, + 0.97919601155444980, 0.97965598059818149, 0.98010700894519687, 0.98055100394412875, + 0.98098802519962192, 0.98141598654910922, 0.98183697415515780, 0.98225098801776767, + 0.98265802813693881, 0.98305702162906528, 0.98344898177310824, 0.98383402777835727, + 0.98421198083087802, 0.98458301974460483, 0.98494702531024814, 0.98530501080676913, + 0.98565500928089023, 0.98600000096485019, 0.98633801890537143, 0.98666900349780917, + 0.98699402762576938, 0.98731297207996249, 0.98762500239536166, 0.98793202592059970, + 0.98823201609775424, 0.98852699948474765, 0.98881602240726352, 0.98909902526065707, + 0.98937600804492831, 0.98964798403903842, 0.98991399956867099, 0.99017500830814242, + 0.99042999697849154, 0.99067997885867953, 0.99092501355335116, 0.99116498185321689, + 0.99140000296756625, 0.99162900401279330, 0.99185401154682040, 0.99207401229068637, + 0.99228900624439120, 0.99250000668689609, 0.99270600033923984, 0.99290698720142245, + 0.99310398055240512, 0.99329698039218783, 0.99348497344180942, 0.99366897298023105, + 0.99384802533313632, 0.99402397824451327, 0.99419599724933505, 0.99436300946399570, + 0.99452698184177279, 0.99468702031299472, 0.99484300566837192, 0.99499499751254916, + 0.99514400912448764, 0.99528902722522616, 0.99542999221011996, 0.99556899024173617, + 0.99570298148319125, 0.99583500577136874, 0.99596297694370151, 0.99608802748844028, + 0.99620902491733432, 0.99632799578830600, 0.99644398642703891, 0.99655598355457187, + 0.99666601372882724, 0.99677300406619906, 0.99687701417133212, 0.99697798443958163, + 0.99707698775455356, 0.99717301083728671, 0.99726700736209750, 0.99735701037570834, + 0.99744600011035800, 0.99753200961276889, 0.99761497927829623, 0.99769699526950717, + 0.99777597142383456, 0.99785298062488437, 0.99792700959369540, 0.99800002528354526, + 0.99807000113651156, 0.99813801003620028, 0.99820500565692782, 0.99826902104541659, + 0.99833202315494418, 0.99839198542758822, 0.99845099402591586, 0.99850797606632113, + 0.99856299115344882, 0.99861699296161532, 0.99866902781650424, 0.99871897650882602, + 0.99876797152683139, 0.99881499959155917, 0.99886101437732577, 0.99890500260517001, + 0.99894797755405307, 0.99898999882861972, 0.99902999354526401, 0.99906802130863070, + 0.99910598946735263, 0.99914199067279696, 0.99917697859928012, 0.99921101285144687, + 0.99924397422000766, 0.99927502823993564, 0.99930602265521884, 0.99933499051257968, + 0.99936401797458529, 0.99939101887866855, 0.99941700650379062, 0.99944299412891269, + 0.99946701480075717, 0.99949097586795688, 0.99951398326084018, 0.99953597737476230, + 0.99955701781436801, 0.99957698537036777, 0.99959701253101230, 0.99961501313373446, + 0.99963402701541781, 0.99965101433917880, 0.99966800166293979, 0.99968397570773959, + 0.99969899607822299, 0.99971401644870639, 0.99972802354022861, 0.99974101735278964, + 0.99975401116535068, 0.99976700497791171, 0.99977898551151156, 0.99979001237079501, + 0.99980097962543368, 0.99981200648471713, 0.99982202006503940, 0.99983102036640048, + 0.99984097434207797, 0.99984902096912265, 0.99985802127048373, 0.99986600829288363, + 0.99987298203632236, 0.99988001538440585, 0.99988698912784457, 0.99989402247592807, + 0.99989998294040561, 0.99990600300952792, 0.99991202307865024, 0.99991697026416659, + 0.99992197705432773, 0.99992698384448886, 0.99993199063464999, 0.99993598414584994, + 0.99993997765704989, 0.99994397116824985, 0.99994802428409457, 0.99995100451633334, + 0.99995499802753329, 0.99995797825977206, 0.99996101809665561, 0.99996399832889438, + 0.99996602488681674, 0.99996900511905551, 0.99997097207233310, 0.99997299863025546, + 0.99997502518817782, 0.99997699214145541, 0.99997901869937778, 0.99998098565265536, + 0.99998199893161654, 0.99998402548953891, 0.99998497916385531, 0.99998700572177768, + 0.99998801900073886, 0.99998897267505527, 0.99998998595401645, 0.99999099923297763, + 0.99999201251193881, 0.99999302579089999, 0.99999302579089999, 0.99999397946521640, + 0.99999499274417758, 0.99999499274417758, 0.99999600602313876, 0.99999600602313876, + 0.99999701930209994, 0.99999701930209994, 0.99999797297641635, 0.99999797297641635, + 0.99999797297641635, 0.99999797297641635, 0.99999898625537753, 0.99999898625537753, + 0.99999898625537753, 0.99999898625537753, 0.99999898625537753, 0.99999999953433871, + 0.99999999953433871, 0.99999999953433871, 0.99999999953433871, 0.99999999953433871, +}; +const FLOAT64 iexheaac_kbd_win_192[192] = { + 0.00003599980846047, 0.00007899990305305, 0.00013699987903237, 0.00021199975162745, + 0.00030699977651238, 0.00042499974370003, 0.00056899990886450, 0.00074399961158633, + 0.00095199979841709, 0.00119899958372116, 0.00148799968883395, 0.00182499969378114, + 0.00221499986946583, 0.00266299955546856, 0.00317399948835373, 0.00375499948859215, + 0.00441099936142564, 0.00514999963343143, 0.00597899965941906, 0.00690299971029162, + 0.00793199939653277, 0.00907099945470691, 0.01032899925485253, 0.01171499909833074, + 0.01323499949648976, 0.01489899912849069, 0.01671499898657203, 0.01869099913164973, + 0.02083599893376231, 0.02315999893471599, 0.02566999895498157, 0.02837499929592013, + 0.03128499863669276, 0.03440799890086055, 0.03775199828669429, 0.04132600082084537, + 0.04513800097629428, 0.04919699905440211, 0.05350999860092998, 0.05808499781414866, + 0.06292799813672900, 0.06804799987003207, 0.07344999862834811, 0.07914099795743823, + 0.08512499881908298, 0.09140899730846286, 0.09799700183793902, 0.10489299846813083, + 0.11209999723359942, 0.11962199909612536, 0.12745900405570865, 0.13561399234458804, + 0.14408799959346652, 0.15287999762222171, 0.16199000133201480, 0.17141500068828464, + 0.18115499569103122, 0.19120599282905459, 0.20156300021335483, 0.21222299290820956, + 0.22317899717018008, 0.23442600620910525, 0.24595500482246280, 0.25775998784229159, + 0.26983100129291415, 0.28215900016948581, 0.29473298741504550, 0.30754300905391574, + 0.32057699514552951, 0.33382099820300937, 0.34726399136707187, 0.36089101387187839, + 0.37468799902126193, 0.38863998604938388, 0.40273100091144443, 0.41694599343463778, + 0.43126800609752536, 0.44568100525066257, 0.46016699029132724, 0.47470900369808078, + 0.48928999854251742, 0.50389099074527621, 0.51849502278491855, 0.53308498812839389, + 0.54764199210330844, 0.56214797450229526, 0.57658499432727695, 0.59093701792880893, + 0.60518497182056308, 0.61931401444599032, 0.63330501271411777, 0.64714300585910678, + 0.66081201983615756, 0.67429697467014194, 0.68758201552554965, 0.70065498305484653, + 0.71350002242252231, 0.72610598756000400, 0.73846000386402011, 0.75055098487064242, + 0.76236897660419345, 0.77390199853107333, 0.78514397097751498, 0.79608499957248569, + 0.80671799136325717, 0.81703698588535190, 0.82703697634860873, 0.83671301556751132, + 0.84606200410053134, 0.85508000804111362, 0.86376702738925815, 0.87212097598239779, + 0.88014298630878329, 0.88783299876376987, 0.89519202662631869, 0.90222400380298495, + 0.90893101645633578, 0.91531801177188754, 0.92138999653980136, 0.92715102387592196, + 0.93260800791904330, 0.93776702834293246, 0.94263601256534457, 0.94722300721332431, + 0.95153397275134921, 0.95557999564334750, 0.95936799002811313, 0.96290802909061313, + 0.96620899392291903, 0.96928101731464267, 0.97213399363681674, 0.97477698279544711, + 0.97722101164981723, 0.97947502089664340, 0.98154997779056430, 0.98345500184223056, + 0.98519897414371371, 0.98679298115894198, 0.98824500991031528, 0.98956501437351108, + 0.99076199484989047, 0.99184399796649814, 0.99282002402469516, 0.99369698716327548, + 0.99448299361392856, 0.99518698407337070, 0.99581301165744662, 0.99637001706287265, + 0.99686300707980990, 0.99729901505634189, 0.99768197489902377, 0.99801802588626742, + 0.99831199599429965, 0.99856698466464877, 0.99878901196643710, 0.99898099852725863, + 0.99914598418399692, 0.99928700877353549, 0.99940800620242953, 0.99951100302860141, + 0.99959701253101230, 0.99967002822086215, 0.99973201705142856, 0.99978297902271152, + 0.99982500029727817, 0.99985998822376132, 0.99988901568576694, 0.99991202307865024, + 0.99993097735568881, 0.99994701100513339, 0.99995899153873324, 0.99996900511905551, + 0.99997597886249423, 0.99998199893161654, 0.99998700572177768, 0.99998998595401645, + 0.99999302579089999, 0.99999499274417758, 0.99999600602313876, 0.99999797297641635, + 0.99999797297641635, 0.99999898625537753, 0.99999898625537753, 0.99999999953433871, + 0.99999999953433871, 0.99999999953433871, 0.99999999953433871, 0.99999999953433871, + 0.99999999953433871, 0.99999999953433871, 0.99999999953433871, 0.99999999953433871, +}; +const FLOAT64 iexheaac_kbd_win_96[96] = { + 0.00005099968984723, 0.00016599986702204, 0.00035499967634678, 0.00064299954101443, + 0.00105799967423081, 0.00163599988445640, 0.00241299951449037, 0.00343399960547686, + 0.00474499957635999, 0.00639999937266111, 0.00845399918034673, 0.01096799923107028, + 0.01400599954649806, 0.01763400016352534, 0.02192199928686023, 0.02693899860605597, + 0.03275499818846583, 0.03943999810144305, 0.04706099955365062, 0.05568399978801608, + 0.06536799622699618, 0.07616899861022830, 0.08813600195571780, 0.10130900098010898, + 0.11572100175544620, 0.13139399839565158, 0.14833900285884738, 0.16655699862167239, + 0.18603500677272677, 0.20674900664016604, 0.22866100026294589, 0.25172099424526095, + 0.27586299134418368, 0.30101299239322543, 0.32708099437877536, 0.35396799398586154, + 0.38156300736591220, 0.40974798751994967, 0.43839499307796359, 0.46736898971721530, + 0.49653398944064975, 0.52574598742648959, 0.55486202193424106, 0.58374100876972079, + 0.61224102927371860, 0.64022701932117343, 0.66756802750751376, 0.69414299679920077, + 0.71983700944110751, 0.74454897595569491, 0.76818597270175815, 0.79067099047824740, + 0.81194001389667392, 0.83194202138110995, 0.85064202500507236, 0.86801701737567782, + 0.88406199170276523, 0.89878302766010165, 0.91219901992008090, 0.92434298945590854, + 0.93525797082111239, 0.94499599887058139, 0.95362001610919833, 0.96119701815769076, + 0.96780002070590854, 0.97350597335025668, 0.97839397145435214, 0.98254299117252231, + 0.98603200865909457, 0.98893701983615756, 0.99133002711459994, 0.99328201962634921, + 0.99485498620197177, 0.99610799504444003, 0.99709498835727572, 0.99786102725192904, + 0.99844801379367709, 0.99889200879260898, 0.99922198010608554, 0.99946302128955722, + 0.99963700724765658, 0.99975997162982821, 0.99984401417896152, 0.99990200949832797, + 0.99993997765704989, 0.99996399832889438, 0.99997901869937778, 0.99998897267505527, + 0.99999397946521640, 0.99999701930209994, 0.99999898625537753, 0.99999898625537753, + 0.99999999953433871, 0.99999999953433871, 0.99999999953433871, 0.99999999953433871, +}; + +const FLOAT64 iusace_kbd_win256[] = { + 0.0005851230124487, 0.0009642149851497, 0.0013558207534965, 0.0017771849644394, + 0.0022352533849672, 0.0027342299070304, 0.0032773001022195, 0.0038671998069216, + 0.0045064443384152, 0.0051974336885144, 0.0059425050016407, 0.0067439602523141, + 0.0076040812644888, 0.0085251378135895, 0.0095093917383048, 0.0105590986429280, + 0.0116765080854300, 0.0128638627792770, 0.0141233971318631, 0.0154573353235409, + 0.0168678890600951, 0.0183572550877256, 0.0199276125319803, 0.0215811201042484, + 0.0233199132076965, 0.0251461009666641, 0.0270617631981826, 0.0290689473405856, + 0.0311696653515848, 0.0333658905863535, 0.0356595546648444, 0.0380525443366107, + 0.0405466983507029, 0.0431438043376910, 0.0458455957104702, 0.0486537485902075, + 0.0515698787635492, 0.0545955386770205, 0.0577322144743916, 0.0609813230826460, + 0.0643442093520723, 0.0678221432558827, 0.0714163171546603, 0.0751278431308314, + 0.0789577503982528, 0.0829069827918993, 0.0869763963425241, 0.0911667569410503, + 0.0954787380973307, 0.0999129187977865, 0.1044697814663005, 0.1091497100326053, + 0.1139529881122542, 0.1188797973021148, 0.1239302155951605, 0.1291042159181728, + 0.1344016647957880, 0.1398223211441467, 0.1453658351972151, 0.1510317475686540, + 0.1568194884519144, 0.1627283769610327, 0.1687576206143887, 0.1749063149634756, + 0.1811734433685097, 0.1875578769224857, 0.1940583745250518, 0.2006735831073503, + 0.2074020380087318, 0.2142421635060113, 0.2211922734956977, 0.2282505723293797, + 0.2354151558022098, 0.2426840122941792, 0.2500550240636293, 0.2575259686921987, + 0.2650945206801527, 0.2727582531907993, 0.2805146399424422, 0.2883610572460804, + 0.2962947861868143, 0.3043130149466800, 0.3124128412663888, 0.3205912750432127, + 0.3288452410620226, 0.3371715818562547, 0.3455670606953511, 0.3540283646950029, + 0.3625521080463003, 0.3711348353596863, 0.3797730251194006, 0.3884630932439016, + 0.3972013967475546, 0.4059842374986933, 0.4148078660689724, 0.4236684856687616, + 0.4325622561631607, 0.4414852981630577, 0.4504336971855032, 0.4594035078775303, + 0.4683907582974173, 0.4773914542472655, 0.4864015836506502, 0.4954171209689973, + 0.5044340316502417, 0.5134482766032377, 0.5224558166913167, 0.5314526172383208, + 0.5404346525403849, 0.5493979103766972, 0.5583383965124314, 0.5672521391870222, + 0.5761351935809411, 0.5849836462541291, 0.5937936195492526, 0.6025612759529649, + 0.6112828224083939, 0.6199545145721097, 0.6285726610088878, 0.6371336273176413, + 0.6456338401819751, 0.6540697913388968, 0.6624380414593221, 0.6707352239341151, + 0.6789580485595255, 0.6871033051160131, 0.6951678668345944, 0.7031486937449871, + 0.7110428359000029, 0.7188474364707993, 0.7265597347077880, 0.7341770687621900, + 0.7416968783634273, 0.7491167073477523, 0.7564342060337386, 0.7636471334404891, + 0.7707533593446514, 0.7777508661725849, 0.7846377507242818, 0.7914122257259034, + 0.7980726212080798, 0.8046173857073919, 0.8110450872887550, 0.8173544143867162, + 0.8235441764639875, 0.8296133044858474, 0.8355608512093652, 0.8413859912867303, + 0.8470880211822968, 0.8526663589032990, 0.8581205435445334, 0.8634502346476508, + 0.8686552113760616, 0.8737353715068081, 0.8786907302411250, 0.8835214188357692, + 0.8882276830575707, 0.8928098814640207, 0.8972684835130879, 0.9016040675058185, + 0.9058173183656508, 0.9099090252587376, 0.9138800790599416, 0.9177314696695282, + 0.9214642831859411, 0.9250796989403991, 0.9285789863994010, 0.9319635019415643, + 0.9352346855155568, 0.9383940571861993, 0.9414432135761304, 0.9443838242107182, + 0.9472176277741918, 0.9499464282852282, 0.9525720912004834, 0.9550965394547873, + 0.9575217494469370, 0.9598497469802043, 0.9620826031668507, 0.9642224303060783, + 0.9662713777449607, 0.9682316277319895, 0.9701053912729269, 0.9718949039986892, + 0.9736024220549734, 0.9752302180233160, 0.9767805768831932, 0.9782557920246753, + 0.9796581613210076, 0.9809899832703159, 0.9822535532154261, 0.9834511596505429, + 0.9845850806232530, 0.9856575802399989, 0.9866709052828243, 0.9876272819448033, + 0.9885289126911557, 0.9893779732525968, 0.9901766097569984, 0.9909269360049311, + 0.9916310308941294, 0.9922909359973702, 0.9929086532976777, 0.9934861430841844, + 0.9940253220113651, 0.9945280613237534, 0.9949961852476154, 0.9954314695504363, + 0.9958356402684387, 0.9962103726017252, 0.9965572899760172, 0.9968779632693499, + 0.9971739102014799, 0.9974465948831872, 0.9976974275220812, 0.9979277642809907, + 0.9981389072844972, 0.9983321047686901, 0.9985085513687731, 0.9986693885387259, + 0.9988157050968516, 0.9989485378906924, 0.9990688725744943, 0.9991776444921379, + 0.9992757396582338, 0.9993639958299003, 0.9994432036616085, 0.9995141079353859, + 0.9995774088586188, 0.9996337634216871, 0.9996837868076957, 0.9997280538466377, + 0.9997671005064359, 0.9998014254134544, 0.9998314913952471, 0.9998577270385304, + 0.9998805282555989, 0.9999002598526793, 0.9999172570940037, 0.9999318272557038, + 0.9999442511639580, 0.9999547847121726, 0.9999636603523446, 0.9999710885561258, + 0.9999772592414866, 0.9999823431612708, 0.9999864932503106, 0.9999898459281599, + 0.9999925223548691, 0.9999946296375997, 0.9999962619864214, 0.9999975018180320, + 0.9999984208055542, 0.9999990808746198, 0.9999995351446231, 0.9999998288155155}; + +const FLOAT64 iusace_sine_win_1024[1024] = { + 0.0007669903, 0.0023009692, 0.0038349426, 0.0053689070, 0.0069028587, 0.0084367942, + 0.0099707099, 0.0115046021, 0.0130384672, 0.0145723017, 0.0161061019, 0.0176398641, + 0.0191735849, 0.0207072605, 0.0222408874, 0.0237744620, 0.0253079806, 0.0268414397, + 0.0283748356, 0.0299081648, 0.0314414235, 0.0329746083, 0.0345077155, 0.0360407415, + 0.0375736827, 0.0391065355, 0.0406392962, 0.0421719614, 0.0437045273, 0.0452369903, + 0.0467693469, 0.0483015934, 0.0498337263, 0.0513657420, 0.0528976367, 0.0544294070, + 0.0559610492, 0.0574925597, 0.0590239350, 0.0605551713, 0.0620862652, 0.0636172130, + 0.0651480110, 0.0666786558, 0.0682091437, 0.0697394710, 0.0712696343, 0.0727996298, + 0.0743294541, 0.0758591034, 0.0773885743, 0.0789178630, 0.0804469661, 0.0819758798, + 0.0835046006, 0.0850331250, 0.0865614492, 0.0880895698, 0.0896174831, 0.0911451855, + 0.0926726734, 0.0941999433, 0.0957269915, 0.0972538144, 0.0987804085, 0.1003067702, + 0.1018328958, 0.1033587818, 0.1048844246, 0.1064098206, 0.1079349662, 0.1094598578, + 0.1109844919, 0.1125088648, 0.1140329729, 0.1155568127, 0.1170803806, 0.1186036730, + 0.1201266864, 0.1216494170, 0.1231718614, 0.1246940159, 0.1262158771, 0.1277374412, + 0.1292587048, 0.1307796642, 0.1323003158, 0.1338206562, 0.1353406817, 0.1368603886, + 0.1383797736, 0.1398988329, 0.1414175630, 0.1429359604, 0.1444540214, 0.1459717425, + 0.1474891201, 0.1490061507, 0.1505228306, 0.1520391563, 0.1535551243, 0.1550707309, + 0.1565859727, 0.1581008460, 0.1596153472, 0.1611294729, 0.1626432194, 0.1641565832, + 0.1656695607, 0.1671821484, 0.1686943427, 0.1702061401, 0.1717175369, 0.1732285296, + 0.1747391148, 0.1762492887, 0.1777590480, 0.1792683889, 0.1807773080, 0.1822858017, + 0.1837938665, 0.1853014988, 0.1868086951, 0.1883154518, 0.1898217653, 0.1913276322, + 0.1928330489, 0.1943380118, 0.1958425174, 0.1973465622, 0.1988501427, 0.2003532552, + 0.2018558962, 0.2033580623, 0.2048597498, 0.2063609553, 0.2078616752, 0.2093619060, + 0.2108616441, 0.2123608861, 0.2138596284, 0.2153578674, 0.2168555996, 0.2183528216, + 0.2198495298, 0.2213457206, 0.2228413906, 0.2243365363, 0.2258311540, 0.2273252404, + 0.2288187918, 0.2303118048, 0.2318042758, 0.2332962014, 0.2347875781, 0.2362784022, + 0.2377686704, 0.2392583790, 0.2407475247, 0.2422361039, 0.2437241130, 0.2452115487, + 0.2466984073, 0.2481846855, 0.2496703796, 0.2511554862, 0.2526400019, 0.2541239230, + 0.2556072462, 0.2570899679, 0.2585720847, 0.2600535930, 0.2615344894, 0.2630147704, + 0.2644944324, 0.2659734721, 0.2674518859, 0.2689296704, 0.2704068221, 0.2718833375, + 0.2733592131, 0.2748344454, 0.2763090311, 0.2777829666, 0.2792562484, 0.2807288731, + 0.2822008372, 0.2836721373, 0.2851427698, 0.2866127314, 0.2880820186, 0.2895506279, + 0.2910185558, 0.2924857990, 0.2939523539, 0.2954182171, 0.2968833852, 0.2983478546, + 0.2998116220, 0.3012746840, 0.3027370370, 0.3041986776, 0.3056596025, 0.3071198080, + 0.3085792909, 0.3100380477, 0.3114960750, 0.3129533692, 0.3144099271, 0.3158657451, + 0.3173208198, 0.3187751479, 0.3202287258, 0.3216815502, 0.3231336177, 0.3245849248, + 0.3260354681, 0.3274852443, 0.3289342498, 0.3303824813, 0.3318299354, 0.3332766087, + 0.3347224977, 0.3361675991, 0.3376119095, 0.3390554254, 0.3404981435, 0.3419400604, + 0.3433811727, 0.3448214769, 0.3462609698, 0.3476996478, 0.3491375077, 0.3505745461, + 0.3520107595, 0.3534461445, 0.3548806979, 0.3563144163, 0.3577472962, 0.3591793342, + 0.3606105271, 0.3620408715, 0.3634703639, 0.3648990010, 0.3663267795, 0.3677536960, + 0.3691797471, 0.3706049296, 0.3720292399, 0.3734526748, 0.3748752310, 0.3762969050, + 0.3777176936, 0.3791375934, 0.3805566010, 0.3819747131, 0.3833919265, 0.3848082376, + 0.3862236433, 0.3876381401, 0.3890517248, 0.3904643940, 0.3918761445, 0.3932869727, + 0.3946968756, 0.3961058497, 0.3975138917, 0.3989209983, 0.4003271663, 0.4017323922, + 0.4031366728, 0.4045400048, 0.4059423848, 0.4073438097, 0.4087442760, 0.4101437805, + 0.4115423199, 0.4129398909, 0.4143364902, 0.4157321146, 0.4171267607, 0.4185204252, + 0.4199131049, 0.4213047965, 0.4226954968, 0.4240852024, 0.4254739101, 0.4268616166, + 0.4282483187, 0.4296340131, 0.4310186965, 0.4324023656, 0.4337850173, 0.4351666482, + 0.4365472552, 0.4379268349, 0.4393053841, 0.4406828996, 0.4420593782, 0.4434348165, + 0.4448092114, 0.4461825596, 0.4475548579, 0.4489261030, 0.4502962918, 0.4516654210, + 0.4530334874, 0.4544004877, 0.4557664188, 0.4571312775, 0.4584950604, 0.4598577645, + 0.4612193865, 0.4625799232, 0.4639393714, 0.4652977279, 0.4666549895, 0.4680111530, + 0.4693662153, 0.4707201731, 0.4720730232, 0.4734247626, 0.4747753878, 0.4761248960, + 0.4774732837, 0.4788205479, 0.4801666854, 0.4815116930, 0.4828555675, 0.4841983059, + 0.4855399049, 0.4868803613, 0.4882196721, 0.4895578341, 0.4908948441, 0.4922306990, + 0.4935653955, 0.4948989307, 0.4962313014, 0.4975625043, 0.4988925365, 0.5002213947, + 0.5015490759, 0.5028755768, 0.5042008944, 0.5055250256, 0.5068479673, 0.5081697163, + 0.5094902695, 0.5108096238, 0.5121277762, 0.5134447234, 0.5147604625, 0.5160749903, + 0.5173883037, 0.5187003997, 0.5200112751, 0.5213209269, 0.5226293519, 0.5239365472, + 0.5252425096, 0.5265472360, 0.5278507234, 0.5291529688, 0.5304539689, 0.5317537209, + 0.5330522216, 0.5343494680, 0.5356454570, 0.5369401856, 0.5382336507, 0.5395258493, + 0.5408167784, 0.5421064348, 0.5433948156, 0.5446819178, 0.5459677383, 0.5472522740, + 0.5485355220, 0.5498174793, 0.5510981428, 0.5523775095, 0.5536555764, 0.5549323405, + 0.5562077987, 0.5574819482, 0.5587547859, 0.5600263088, 0.5612965138, 0.5625653981, + 0.5638329586, 0.5650991924, 0.5663640964, 0.5676276677, 0.5688899033, 0.5701508003, + 0.5714103557, 0.5726685665, 0.5739254297, 0.5751809424, 0.5764351017, 0.5776879046, + 0.5789393481, 0.5801894293, 0.5814381452, 0.5826854930, 0.5839314697, 0.5851760723, + 0.5864192980, 0.5876611437, 0.5889016066, 0.5901406838, 0.5913783724, 0.5926146693, + 0.5938495718, 0.5950830769, 0.5963151817, 0.5975458833, 0.5987751788, 0.6000030654, + 0.6012295401, 0.6024546000, 0.6036782423, 0.6049004641, 0.6061212625, 0.6073406346, + 0.6085585777, 0.6097750887, 0.6109901648, 0.6122038032, 0.6134160011, 0.6146267555, + 0.6158360637, 0.6170439227, 0.6182503298, 0.6194552821, 0.6206587767, 0.6218608109, + 0.6230613817, 0.6242604865, 0.6254581222, 0.6266542863, 0.6278489757, 0.6290421878, + 0.6302339196, 0.6314241685, 0.6326129316, 0.6338002060, 0.6349859891, 0.6361702780, + 0.6373530699, 0.6385343621, 0.6397141517, 0.6408924360, 0.6420692122, 0.6432444776, + 0.6444182294, 0.6455904648, 0.6467611810, 0.6479303754, 0.6490980451, 0.6502641875, + 0.6514287997, 0.6525918790, 0.6537534227, 0.6549134281, 0.6560718923, 0.6572288128, + 0.6583841868, 0.6595380115, 0.6606902843, 0.6618410024, 0.6629901631, 0.6641377638, + 0.6652838016, 0.6664282740, 0.6675711782, 0.6687125116, 0.6698522714, 0.6709904550, + 0.6721270597, 0.6732620828, 0.6743955216, 0.6755273735, 0.6766576359, 0.6777863060, + 0.6789133812, 0.6800388589, 0.6811627363, 0.6822850110, 0.6834056801, 0.6845247411, + 0.6856421914, 0.6867580283, 0.6878722492, 0.6889848514, 0.6900958324, 0.6912051896, + 0.6923129202, 0.6934190218, 0.6945234917, 0.6956263273, 0.6967275261, 0.6978270854, + 0.6989250026, 0.7000212752, 0.7011159006, 0.7022088761, 0.7033001994, 0.7043898676, + 0.7054778784, 0.7065642291, 0.7076489173, 0.7087319402, 0.7098132954, 0.7108929804, + 0.7119709926, 0.7130473294, 0.7141219884, 0.7151949669, 0.7162662626, 0.7173358728, + 0.7184037950, 0.7194700268, 0.7205345656, 0.7215974089, 0.7226585542, 0.7237179990, + 0.7247757408, 0.7258317772, 0.7268861056, 0.7279387236, 0.7289896287, 0.7300388184, + 0.7310862903, 0.7321320418, 0.7331760705, 0.7342183741, 0.7352589499, 0.7362977956, + 0.7373349087, 0.7383702868, 0.7394039274, 0.7404358282, 0.7414659866, 0.7424944003, + 0.7435210669, 0.7445459838, 0.7455691488, 0.7465905593, 0.7476102131, 0.7486281077, + 0.7496442407, 0.7506586097, 0.7516712123, 0.7526820461, 0.7536911089, 0.7546983981, + 0.7557039114, 0.7567076465, 0.7577096010, 0.7587097726, 0.7597081588, 0.7607047573, + 0.7616995659, 0.7626925820, 0.7636838035, 0.7646732280, 0.7656608531, 0.7666466766, + 0.7676306960, 0.7686129092, 0.7695933137, 0.7705719073, 0.7715486876, 0.7725236525, + 0.7734967995, 0.7744681264, 0.7754376309, 0.7764053107, 0.7773711636, 0.7783351872, + 0.7792973794, 0.7802577378, 0.7812162601, 0.7821729442, 0.7831277877, 0.7840807885, + 0.7850319443, 0.7859812528, 0.7869287118, 0.7878743191, 0.7888180724, 0.7897599696, + 0.7907000084, 0.7916381866, 0.7925745020, 0.7935089524, 0.7944415356, 0.7953722494, + 0.7963010916, 0.7972280601, 0.7981531526, 0.7990763669, 0.7999977010, 0.8009171525, + 0.8018347195, 0.8027503996, 0.8036641908, 0.8045760909, 0.8054860978, 0.8063942092, + 0.8073004232, 0.8082047375, 0.8091071500, 0.8100076586, 0.8109062612, 0.8118029556, + 0.8126977398, 0.8135906116, 0.8144815690, 0.8153706098, 0.8162577319, 0.8171429334, + 0.8180262120, 0.8189075657, 0.8197869925, 0.8206644902, 0.8215400568, 0.8224136902, + 0.8232853885, 0.8241551494, 0.8250229711, 0.8258888513, 0.8267527882, 0.8276147797, + 0.8284748237, 0.8293329182, 0.8301890612, 0.8310432507, 0.8318954847, 0.8327457612, + 0.8335940781, 0.8344404335, 0.8352848254, 0.8361272517, 0.8369677106, 0.8378062000, + 0.8386427180, 0.8394772626, 0.8403098317, 0.8411404236, 0.8419690362, 0.8427956675, + 0.8436203157, 0.8444429788, 0.8452636547, 0.8460823417, 0.8468990378, 0.8477137411, + 0.8485264496, 0.8493371614, 0.8501458747, 0.8509525875, 0.8517572979, 0.8525600040, + 0.8533607040, 0.8541593960, 0.8549560780, 0.8557507483, 0.8565434048, 0.8573340459, + 0.8581226695, 0.8589092739, 0.8596938573, 0.8604764176, 0.8612569532, 0.8620354622, + 0.8628119427, 0.8635863929, 0.8643588111, 0.8651291953, 0.8658975438, 0.8666638547, + 0.8674281263, 0.8681903567, 0.8689505443, 0.8697086870, 0.8704647833, 0.8712188313, + 0.8719708293, 0.8727207754, 0.8734686679, 0.8742145050, 0.8749582850, 0.8757000062, + 0.8764396668, 0.8771772650, 0.8779127992, 0.8786462675, 0.8793776683, 0.8801069998, + 0.8808342603, 0.8815594482, 0.8822825617, 0.8830035990, 0.8837225586, 0.8844394387, + 0.8851542376, 0.8858669537, 0.8865775852, 0.8872861306, 0.8879925880, 0.8886969560, + 0.8893992327, 0.8900994166, 0.8907975060, 0.8914934993, 0.8921873948, 0.8928791909, + 0.8935688860, 0.8942564784, 0.8949419666, 0.8956253488, 0.8963066236, 0.8969857893, + 0.8976628443, 0.8983377870, 0.8990106158, 0.8996813291, 0.9003499254, 0.9010164032, + 0.9016807607, 0.9023429965, 0.9030031090, 0.9036610966, 0.9043169578, 0.9049706911, + 0.9056222949, 0.9062717677, 0.9069191080, 0.9075643141, 0.9082073847, 0.9088483182, + 0.9094871131, 0.9101237679, 0.9107582810, 0.9113906511, 0.9120208766, 0.9126489560, + 0.9132748878, 0.9138986706, 0.9145203030, 0.9151397833, 0.9157571103, 0.9163722824, + 0.9169852982, 0.9175961562, 0.9182048551, 0.9188113933, 0.9194157694, 0.9200179821, + 0.9206180299, 0.9212159114, 0.9218116252, 0.9224051699, 0.9229965440, 0.9235857463, + 0.9241727753, 0.9247576296, 0.9253403078, 0.9259208087, 0.9264991307, 0.9270752727, + 0.9276492331, 0.9282210107, 0.9287906041, 0.9293580119, 0.9299232329, 0.9304862657, + 0.9310471089, 0.9316057614, 0.9321622216, 0.9327164884, 0.9332685604, 0.9338184364, + 0.9343661149, 0.9349115949, 0.9354548749, 0.9359959536, 0.9365348299, 0.9370715025, + 0.9376059700, 0.9381382312, 0.9386682849, 0.9391961298, 0.9397217647, 0.9402451884, + 0.9407663995, 0.9412853970, 0.9418021795, 0.9423167459, 0.9428290949, 0.9433392253, + 0.9438471359, 0.9443528256, 0.9448562932, 0.9453575374, 0.9458565571, 0.9463533511, + 0.9468479182, 0.9473402573, 0.9478303673, 0.9483182469, 0.9488038950, 0.9492873104, + 0.9497684922, 0.9502474390, 0.9507241498, 0.9511986234, 0.9516708588, 0.9521408548, + 0.9526086104, 0.9530741243, 0.9535373956, 0.9539984231, 0.9544572058, 0.9549137425, + 0.9553680322, 0.9558200739, 0.9562698664, 0.9567174087, 0.9571626998, 0.9576057386, + 0.9580465240, 0.9584850551, 0.9589213307, 0.9593553500, 0.9597871117, 0.9602166150, + 0.9606438588, 0.9610688421, 0.9614915640, 0.9619120233, 0.9623302192, 0.9627461506, + 0.9631598166, 0.9635712162, 0.9639803484, 0.9643872123, 0.9647918069, 0.9651941312, + 0.9655941843, 0.9659919653, 0.9663874732, 0.9667807071, 0.9671716661, 0.9675603493, + 0.9679467556, 0.9683308843, 0.9687127345, 0.9690923051, 0.9694695954, 0.9698446044, + 0.9702173313, 0.9705877752, 0.9709559352, 0.9713218104, 0.9716854000, 0.9720467032, + 0.9724057190, 0.9727624467, 0.9731168854, 0.9734690342, 0.9738188923, 0.9741664590, + 0.9745117334, 0.9748547146, 0.9751954019, 0.9755337945, 0.9758698916, 0.9762036923, + 0.9765351960, 0.9768644017, 0.9771913088, 0.9775159165, 0.9778382240, 0.9781582305, + 0.9784759354, 0.9787913378, 0.9791044370, 0.9794152322, 0.9797237229, 0.9800299081, + 0.9803337872, 0.9806353595, 0.9809346243, 0.9812315808, 0.9815262285, 0.9818185664, + 0.9821085941, 0.9823963108, 0.9826817158, 0.9829648084, 0.9832455881, 0.9835240541, + 0.9838002057, 0.9840740424, 0.9843455634, 0.9846147682, 0.9848816561, 0.9851462265, + 0.9854084787, 0.9856684122, 0.9859260263, 0.9861813204, 0.9864342939, 0.9866849463, + 0.9869332769, 0.9871792851, 0.9874229704, 0.9876643322, 0.9879033700, 0.9881400831, + 0.9883744710, 0.9886065332, 0.9888362691, 0.9890636782, 0.9892887599, 0.9895115137, + 0.9897319391, 0.9899500355, 0.9901658026, 0.9903792396, 0.9905903462, 0.9907991219, + 0.9910055661, 0.9912096783, 0.9914114582, 0.9916109052, 0.9918080188, 0.9920027986, + 0.9921952441, 0.9923853549, 0.9925731305, 0.9927585705, 0.9929416744, 0.9931224418, + 0.9933008724, 0.9934769656, 0.9936507210, 0.9938221383, 0.9939912170, 0.9941579568, + 0.9943223572, 0.9944844179, 0.9946441385, 0.9948015186, 0.9949565578, 0.9951092558, + 0.9952596121, 0.9954076266, 0.9955532988, 0.9956966283, 0.9958376149, 0.9959762581, + 0.9961125577, 0.9962465134, 0.9963781248, 0.9965073917, 0.9966343136, 0.9967588904, + 0.9968811217, 0.9970010073, 0.9971185468, 0.9972337400, 0.9973465866, 0.9974570864, + 0.9975652391, 0.9976710443, 0.9977745020, 0.9978756118, 0.9979743735, 0.9980707869, + 0.9981648517, 0.9982565678, 0.9983459348, 0.9984329527, 0.9985176211, 0.9985999399, + 0.9986799090, 0.9987575280, 0.9988327969, 0.9989057154, 0.9989762834, 0.9990445007, + 0.9991103671, 0.9991738826, 0.9992350469, 0.9992938599, 0.9993503214, 0.9994044314, + 0.9994561897, 0.9995055962, 0.9995526508, 0.9995973533, 0.9996397037, 0.9996797018, + 0.9997173475, 0.9997526409, 0.9997855817, 0.9998161699, 0.9998444055, 0.9998702883, + 0.9998938184, 0.9999149956, 0.9999338199, 0.9999502912, 0.9999644096, 0.9999761750, + 0.9999855873, 0.9999926466, 0.9999973528, 0.9999997059}; +const FLOAT64 iexheaac_sine_win_768[768] = { + 0.00102265368033830, 0.00306795676296598, 0.00511324701146473, 0.00715851586980828, + 0.00920375478205982, 0.01124895519240780, 0.01329410854520177, 0.01533920628498810, + 0.01738423985654582, 0.01942920070492239, 0.02147408027546951, 0.02351887001387885, + 0.02556356136621791, 0.02760814577896574, 0.02965261469904877, 0.03169695957387656, + 0.03374117185137759, 0.03578524298003501, 0.03782916440892246, 0.03987292758773980, + 0.04191652396684893, 0.04395994499730949, 0.04600318213091463, 0.04804622682022684, + 0.05008907051861362, 0.05213170468028332, 0.05417412076032079, 0.05621631021472320, + 0.05825826450043575, 0.06029997507538745, 0.06234143339852677, 0.06438263092985747, + 0.06642355913047421, 0.06846420946259842, 0.07050457338961386, 0.07254464237610246, + 0.07458440788787991, 0.07662386139203149, 0.07866299435694764, 0.08070179825235972, + 0.08274026454937569, 0.08477838472051578, 0.08681615023974816, 0.08885355258252459, + 0.09089058322581614, 0.09292723364814875, 0.09496349532963899, 0.09699935975202961, + 0.09903481839872517, 0.10106986275482782, 0.10310448430717267, 0.10513867454436361, + 0.10717242495680886, 0.10920572703675646, 0.11123857227833006, 0.11327095217756435, + 0.11530285823244064, 0.11733428194292254, 0.11936521481099135, 0.12139564834068181, + 0.12342557403811745, 0.12545498341154623, 0.12748386797137606, 0.12951221923021025, + 0.13154002870288312, 0.13356728790649536, 0.13559398836044964, 0.13762012158648604, + 0.13964567910871750, 0.14167065245366528, 0.14369503315029444, 0.14571881273004925, + 0.14774198272688863, 0.14976453467732154, 0.15178646012044233, 0.15380775059796639, + 0.15582839765426523, 0.15784839283640195, 0.15986772769416666, 0.16188639378011183, + 0.16390438264958751, 0.16592168586077685, 0.16793829497473114, 0.16995420155540550, + 0.17196939716969370, 0.17398387338746382, 0.17599762178159339, 0.17801063392800456, + 0.18002290140569954, 0.18203441579679547, 0.18404516868656010, 0.18605515166344663, + 0.18806435631912907, 0.19007277424853736, 0.19208039704989244, 0.19408721632474166, + 0.19609322367799367, 0.19809841071795356, 0.20010276905635813, 0.20210629030841087, + 0.20410896609281687, 0.20611078803181823, 0.20811174775122887, 0.21011183688046958, + 0.21211104705260322, 0.21410936990436930, 0.21610679707621952, 0.21810332021235226, + 0.22009893096074790, 0.22209362097320354, 0.22408738190536787, 0.22608020541677631, + 0.22807208317088573, 0.23006300683510938, 0.23205296808085177, 0.23404195858354343, + 0.23602997002267576, 0.23801699408183588, 0.24000302244874147, 0.24198804681527539, + 0.24397205887752058, 0.24595505033579462, 0.24793701289468467, 0.24991793826308206, + 0.25189781815421691, 0.25387664428569306, 0.25585440837952211, 0.25783110216215899, + 0.25980671736453570, 0.26178124572209621, 0.26375467897483135, 0.26572700886731287, + 0.26769822714872826, 0.26966832557291509, 0.27163729589839575, 0.27360512988841174, + 0.27557181931095814, 0.27753735593881812, 0.27950173154959723, 0.28146493792575794, + 0.28342696685465407, 0.28538781012856484, 0.28734745954472951, 0.28930590690538155, + 0.29126314401778297, 0.29321916269425863, 0.29517395475223041, 0.29712751201425147, + 0.29907982630804048, 0.30103088946651579, 0.30298069332782973, 0.30492922973540237, + 0.30687649053795618, 0.30882246758954962, 0.31076715274961147, 0.31271053788297504, + 0.31465261485991186, 0.31659337555616585, 0.31853281185298737, 0.32047091563716701, + 0.32240767880106985, 0.32434309324266886, 0.32627715086557935, 0.32820984357909255, + 0.33014116329820925, 0.33207110194367423, 0.33399965144200938, 0.33592680372554795, + 0.33785255073246817, 0.33977688440682685, 0.34169979669859302, 0.34362127956368221, + 0.34554132496398909, 0.34745992486742200, 0.34937707124793610, 0.35129275608556709, + 0.35320697136646473, 0.35511970908292623, 0.35703096123342998, 0.35894071982266895, + 0.36084897686158385, 0.36275572436739723, 0.36466095436364598, 0.36656465888021544, + 0.36846682995337232, 0.37036745962579837, 0.37226653994662323, 0.37416406297145793, + 0.37606002076242839, 0.37795440538820796, 0.37984720892405111, 0.38173842345182668, + 0.38362804106005055, 0.38551605384391890, 0.38740245390534150, 0.38928723335297460, + 0.39117038430225387, 0.39305189887542746, 0.39493176920158896, 0.39680998741671031, + 0.39868654566367462, 0.40056143609230926, 0.40243465085941843, 0.40430618212881619, + 0.40617602207135894, 0.40804416286497869, 0.40991059669471525, 0.41177531575274917, + 0.41363831223843450, 0.41549957835833118, 0.41735910632623768, 0.41921688836322391, + 0.42107291669766328, 0.42292718356526549, 0.42477968120910881, 0.42663040187967305, + 0.42847933783487130, 0.43032648134008261, 0.43217182466818455, 0.43401536009958513, + 0.43585707992225547, 0.43769697643176175, 0.43953504193129772, 0.44137126873171662, + 0.44320564915156369, 0.44503817551710784, 0.44686884016237421, 0.44869763542917590, + 0.45052455366714633, 0.45234958723377089, 0.45417272849441909, 0.45599396982237672, + 0.45781330359887717, 0.45963072221313395, 0.46144621806237213, 0.46325978355186020, + 0.46507141109494193, 0.46688109311306797, 0.46868882203582790, 0.47049459030098151, + 0.47229839035449034, 0.47410021465054997, 0.47590005565162086, 0.47769790582846000, + 0.47949375766015301, 0.48128760363414474, 0.48307943624627120, 0.48486924800079112, + 0.48665703141041666, 0.48844277899634531, 0.49022648328829116, 0.49200813682451561, + 0.49378773215185917, 0.49556526182577254, 0.49734071841034722, 0.49911409447834748, + 0.50088538261124071, 0.50265457539922898, 0.50442166544127920, 0.50618664534515523, + 0.50794950772744829, 0.50971024521360719, 0.51146885043797030, 0.51322531604379584, + 0.51497963468329233, 0.51673179901764976, 0.51848180171707059, 0.52022963546079937, + 0.52197529293715439, 0.52371876684355767, 0.52546004988656625, 0.52719913478190128, + 0.52893601425448022, 0.53067068103844606, 0.53240312787719790, 0.53413334752342190, + 0.53586133273912107, 0.53758707629564551, 0.53931057097372281, 0.54103180956348851, + 0.54275078486451589, 0.54446748968584602, 0.54618191684601836, 0.54789405917310019, + 0.54960390950471694, 0.55131146068808212, 0.55301670558002747, 0.55471963704703231, + 0.55642024796525358, 0.55811853122055610, 0.55981447970854170, 0.56150808633457916, + 0.56319934401383409, 0.56488824567129847, 0.56657478424181984, 0.56825895267013149, + 0.56994074391088179, 0.57162015092866314, 0.57329716669804209, 0.57497178420358863, + 0.57664399643990505, 0.57831379641165559, 0.57998117713359565, 0.58164613163060153, + 0.58330865293769829, 0.58496873410009032, 0.58662636817318969, 0.58828154822264522, + 0.58993426732437171, 0.59158451856457883, 0.59323229503979980, 0.59487758985692063, + 0.59652039613320884, 0.59816070699634227, 0.59979851558443753, 0.60143381504607918, + 0.60306659854034816, 0.60469685923685024, 0.60632459031574482, 0.60794978496777363, + 0.60957243639428871, 0.61119253780728122, 0.61281008242940971, 0.61442506349402870, + 0.61603747424521638, 0.61764730793780387, 0.61925455783740246, 0.62085921722043214, + 0.62246127937414997, 0.62406073759667779, 0.62565758519703063, 0.62725181549514408, + 0.62884342182190311, 0.63043239751916935, 0.63201873593980906, 0.63360243044772069, + 0.63518347441786349, 0.63676186123628431, 0.63833758430014542, 0.63991063701775286, + 0.64148101280858316, 0.64304870510331114, 0.64461370734383749, 0.64617601298331639, + 0.64773561548618219, 0.64929250832817775, 0.65084668499638088, 0.65239813898923193, + 0.65394686381656120, 0.65549285299961535, 0.65703610007108570, 0.65857659857513395, + 0.66011434206742048, 0.66164932411513000, 0.66318153829699955, 0.66471097820334479, + 0.66623763743608710, 0.66776150960878000, 0.66928258834663601, 0.67080086728655375, + 0.67231634007714391, 0.67382900037875604, 0.67533884186350535, 0.67684585821529875, + 0.67835004312986136, 0.67985139031476371, 0.68134989348944641, 0.68284554638524808, + 0.68433834274543037, 0.68582827632520493, 0.68731534089175916, 0.68879953022428220, + 0.69028083811399144, 0.69175925836415775, 0.69323478479013223, 0.69470741121937118, + 0.69617713149146299, 0.69764393945815262, 0.69910782898336876, 0.70056879394324834, + 0.70202682822616258, 0.70348192573274260, 0.70493408037590488, 0.70638328608087697, + 0.70782953678522198, 0.70927282643886558, 0.71071314900411964, 0.71215049845570844, + 0.71358486878079352, 0.71501625397899926, 0.71644464806243713, 0.71787004505573171, + 0.71929243899604522, 0.72071182393310229, 0.72212819392921535, 0.72354154305930873, + 0.72495186541094447, 0.72635915508434590, 0.72776340619242341, 0.72916461286079826, + 0.73056276922782759, 0.73195786944462859, 0.73334990767510344, 0.73473887809596350, + 0.73612477489675332, 0.73750759227987561, 0.73888732446061511, 0.74026396566716268, + 0.74163751014063950, 0.74300795213512172, 0.74437528591766333, 0.74573950576832182, + 0.74710060598018013, 0.74845858085937211, 0.74981342472510559, 0.75116513190968637, + 0.75251369675854196, 0.75385911363024471, 0.75520137689653655, 0.75654048094235116, + 0.75787642016583856, 0.75920918897838807, 0.76053878180465140, 0.76186519308256673, + 0.76318841726338116, 0.76450844881167490, 0.76582528220538315, 0.76713891193582040, + 0.76844933250770253, 0.76975653843917091, 0.77106052426181371, 0.77236128452069064, + 0.77365881377435441, 0.77495310659487382, 0.77624415756785703, 0.77753196129247315, + 0.77881651238147598, 0.78009780546122565, 0.78137583517171194, 0.78265059616657573, + 0.78392208311313194, 0.78519029069239199, 0.78645521359908577, 0.78771684654168361, + 0.78897518424241886, 0.79023022143731003, 0.79148195287618217, 0.79273037332268959, + 0.79397547755433717, 0.79521726036250251, 0.79645571655245762, 0.79769084094339104, + 0.79892262836842864, 0.80015107367465621, 0.80137617172314024, 0.80259791738894981, + 0.80381630556117811, 0.80503133114296355, 0.80624298905151137, 0.80745127421811436, + 0.80865618158817498, 0.80985770612122543, 0.81105584279094978, 0.81225058658520388, + 0.81344193250603758, 0.81462987556971456, 0.81581441080673378, 0.81699553326185004, + 0.81817323799409480, 0.81934752007679701, 0.82051837459760291, 0.82168579665849806, + 0.82284978137582632, 0.82401032388031115, 0.82516741931707571, 0.82632106284566342, + 0.82747124964005780, 0.82861797488870270, 0.82976123379452305, 0.83090102157494405, + 0.83203733346191189, 0.83317016470191319, 0.83429951055599527, 0.83542536629978548, + 0.83654772722351189, 0.83766658863202192, 0.83878194584480237, 0.83989379419599952, + 0.84100212903443772, 0.84210694572363964, 0.84320823964184544, 0.84430600618203178, + 0.84540024075193121, 0.84649093877405202, 0.84757809568569653, 0.84866170693898058, + 0.84974176800085244, 0.85081827435311197, 0.85189122149242935, 0.85296060493036363, + 0.85402642019338249, 0.85508866282287954, 0.85614732837519447, 0.85720241242163031, + 0.85825391054847278, 0.85930181835700836, 0.86034613146354322, 0.86138684549942079, + 0.86242395611104050, 0.86345745895987613, 0.86448734972249353, 0.86551362409056909, + 0.86653627777090736, 0.86755530648545953, 0.86857070597134078, 0.86958247198084881, + 0.87059060028148061, 0.87159508665595109, 0.87259592690221022, 0.87359311683346086, + 0.87458665227817611, 0.87557652908011685, 0.87656274309834903, 0.87754529020726124, + 0.87852416629658159, 0.87949936727139499, 0.88047088905216075, 0.88143872757472896, + 0.88240287879035817, 0.88336333866573158, 0.88432010318297449, 0.88527316833967107, + 0.88622253014888064, 0.88716818463915492, 0.88811012785455423, 0.88904835585466457, + 0.88998286471461308, 0.89091365052508575, 0.89184070939234272, 0.89276403743823518, + 0.89368363080022140, 0.89459948563138258, 0.89551159810043990, 0.89641996439176930, + 0.89732458070541832, 0.89822544325712139, 0.89912254827831661, 0.90001589201616017, + 0.90090547073354332, 0.90179128070910730, 0.90267331823725883, 0.90355157962818611, + 0.90442606120787372, 0.90529675931811882, 0.90616367031654510, 0.90702679057661939, + 0.90788611648766615, 0.90874164445488259, 0.90959337089935355, 0.91044129225806714, + 0.91128540498392907, 0.91212570554577754, 0.91296219042839810, 0.91379485613253864, + 0.91462369917492325, 0.91544871608826783, 0.91626990342129366, 0.91708725773874245, + 0.91790077562139039, 0.91871045366606274, 0.91951628848564759, 0.92031827670911059, + 0.92111641498150854, 0.92191069996400399, 0.92270112833387852, 0.92348769678454734, + 0.92427040202557276, 0.92504924078267758, 0.92582420979775970, 0.92659530582890492, + 0.92736252565040100, 0.92812586605275105, 0.92888532384268652, 0.92964089584318133, + 0.93039257889346438, 0.93114036984903348, 0.93188426558166815, 0.93262426297944234, + 0.93336035894673830, 0.93409255040425887, 0.93482083428904061, 0.93554520755446624, + 0.93626566717027826, 0.93698221012259064, 0.93769483341390203, 0.93840353406310806, + 0.93910830910551413, 0.93980915559284706, 0.94050607059326830, 0.94119905119138580, + 0.94188809448826616, 0.94257319760144687, 0.94325435766494814, 0.94393157182928522, + 0.94460483726148026, 0.94527415114507385, 0.94593951068013715, 0.94660091308328353, + 0.94725835558768001, 0.94791183544305924, 0.94856134991573027, 0.94920689628859101, + 0.94984847186113874, 0.95048607394948170, 0.95111969988635059, 0.95174934702110914, + 0.95237501271976588, 0.95299669436498446, 0.95361438935609522, 0.95422809510910567, + 0.95483780905671134, 0.95544352864830695, 0.95604525134999641, 0.95664297464460391, + 0.95723669603168404, 0.95782641302753291, 0.95841212316519775, 0.95899382399448785, + 0.95957151308198452, 0.96014518801105120, 0.96071484638184379, 0.96128048581132064, + 0.96184210393325231, 0.96239969839823170, 0.96295326687368388, 0.96350280704387570, + 0.96404831660992540, 0.96458979328981276, 0.96512723481838780, 0.96566063894738108, + 0.96619000344541250, 0.96671532609800115, 0.96723660470757400, 0.96775383709347551, + 0.96826702109197660, 0.96877615455628396, 0.96928123535654853, 0.96978226137987467, + 0.97027923053032938, 0.97077214072895035, 0.97126098991375498, 0.97174577603974932, + 0.97222649707893627, 0.97270315102032390, 0.97317573586993444, 0.97364424965081187, + 0.97410869040303105, 0.97456905618370515, 0.97502534506699423, 0.97547755514411294, + 0.97592568452333917, 0.97636973133002114, 0.97680969370658577, 0.97724556981254629, + 0.97767735782450993, 0.97810505593618557, 0.97852866235839142, 0.97894817531906220, + 0.97936359306325671, 0.97977491385316551, 0.98018213596811743, 0.98058525770458749, + 0.98098427737620386, 0.98137919331375456, 0.98177000386519475, 0.98215670739565364, + 0.98253930228744124, 0.98291778694005516, 0.98329215977018725, 0.98366241921173025, + 0.98402856371578462, 0.98439059175066435, 0.98474850180190421, 0.98510229237226532, + 0.98545196198174201, 0.98579750916756737, 0.98613893248422035, 0.98647623050343058, + 0.98680940181418542, 0.98713844502273529, 0.98746335875259938, 0.98778414164457218, + 0.98810079235672799, 0.98841330956442774, 0.98872169196032378, 0.98902593825436536, + 0.98932604717380446, 0.98962201746320078, 0.98991384788442716, 0.99020153721667448, + 0.99048508425645698, 0.99076448781761761, 0.99103974673133233, 0.99131085984611544, + 0.99157782602782418, 0.99184064415966378, 0.99209931314219180, 0.99235383189332282, + 0.99260419934833310, 0.99285041445986510, 0.99309247619793128, 0.99333038354991920, + 0.99356413552059530, 0.99379373113210911, 0.99401916942399726, 0.99424044945318790, + 0.99445757029400417, 0.99467053103816849, 0.99487933079480562, 0.99508396869044746, + 0.99528444386903603, 0.99548075549192694, 0.99567290273789333, 0.99586088480312895, + 0.99604470090125197, 0.99622435026330769, 0.99639983213777195, 0.99657114579055484, + 0.99673829050500284, 0.99690126558190251, 0.99706007033948296, 0.99721470411341928, + 0.99736516625683469, 0.99751145614030345, 0.99765357315185388, 0.99779151669697030, + 0.99792528619859600, 0.99805488109713536, 0.99818030085045639, 0.99830154493389289, + 0.99841861284024647, 0.99853150407978930, 0.99864021818026527, 0.99874475468689261, + 0.99884511316236579, 0.99894129318685687, 0.99903329435801769, 0.99912111629098133, + 0.99920475861836389, 0.99928422099026593, 0.99935950307427401, 0.99943060455546173, + 0.99949752513639178, 0.99956026453711622, 0.99961882249517864, 0.99967319876561445, + 0.99972339312095237, 0.99976940535121528, 0.99981123526392113, 0.99984888268408345, + 0.99988234745421256, 0.99991162943431577, 0.99993672850189841, 0.99995764455196390, + 0.99997437749701457, 0.99998692726705174, 0.99999529380957619, 0.99999947708958836, +}; +const FLOAT64 iusace_sine_win_256[256] = { + 0.0030679568, 0.0092037548, 0.0153392063, 0.0214740803, 0.0276081458, 0.0337411719, + 0.0398729276, 0.0460031821, 0.0521317047, 0.0582582645, 0.0643826309, 0.0705045734, + 0.0766238614, 0.0827402645, 0.0888535526, 0.0949634953, 0.1010698628, 0.1071724250, + 0.1132709522, 0.1193652148, 0.1254549834, 0.1315400287, 0.1376201216, 0.1436950332, + 0.1497645347, 0.1558283977, 0.1618863938, 0.1679382950, 0.1739838734, 0.1800229014, + 0.1860551517, 0.1920803970, 0.1980984107, 0.2041089661, 0.2101118369, 0.2161067971, + 0.2220936210, 0.2280720832, 0.2340419586, 0.2400030224, 0.2459550503, 0.2518978182, + 0.2578311022, 0.2637546790, 0.2696683256, 0.2755718193, 0.2814649379, 0.2873474595, + 0.2932191627, 0.2990798263, 0.3049292297, 0.3107671527, 0.3165933756, 0.3224076788, + 0.3282098436, 0.3339996514, 0.3397768844, 0.3455413250, 0.3512927561, 0.3570309612, + 0.3627557244, 0.3684668300, 0.3741640630, 0.3798472089, 0.3855160538, 0.3911703843, + 0.3968099874, 0.4024346509, 0.4080441629, 0.4136383122, 0.4192168884, 0.4247796812, + 0.4303264813, 0.4358570799, 0.4413712687, 0.4468688402, 0.4523495872, 0.4578133036, + 0.4632597836, 0.4686888220, 0.4741002147, 0.4794937577, 0.4848692480, 0.4902264833, + 0.4955652618, 0.5008853826, 0.5061866453, 0.5114688504, 0.5167317990, 0.5219752929, + 0.5271991348, 0.5324031279, 0.5375870763, 0.5427507849, 0.5478940592, 0.5530167056, + 0.5581185312, 0.5631993440, 0.5682589527, 0.5732971667, 0.5783137964, 0.5833086529, + 0.5882815482, 0.5932322950, 0.5981607070, 0.6030665985, 0.6079497850, 0.6128100824, + 0.6176473079, 0.6224612794, 0.6272518155, 0.6320187359, 0.6367618612, 0.6414810128, + 0.6461760130, 0.6508466850, 0.6554928530, 0.6601143421, 0.6647109782, 0.6692825883, + 0.6738290004, 0.6783500431, 0.6828455464, 0.6873153409, 0.6917592584, 0.6961771315, + 0.7005687939, 0.7049340804, 0.7092728264, 0.7135848688, 0.7178700451, 0.7221281939, + 0.7263591551, 0.7305627692, 0.7347388781, 0.7388873245, 0.7430079521, 0.7471006060, + 0.7511651319, 0.7552013769, 0.7592091890, 0.7631884173, 0.7671389119, 0.7710605243, + 0.7749531066, 0.7788165124, 0.7826505962, 0.7864552136, 0.7902302214, 0.7939754776, + 0.7976908409, 0.8013761717, 0.8050313311, 0.8086561816, 0.8122505866, 0.8158144108, + 0.8193475201, 0.8228497814, 0.8263210628, 0.8297612338, 0.8331701647, 0.8365477272, + 0.8398937942, 0.8432082396, 0.8464909388, 0.8497417680, 0.8529606049, 0.8561473284, + 0.8593018184, 0.8624239561, 0.8655136241, 0.8685707060, 0.8715950867, 0.8745866523, + 0.8775452902, 0.8804708891, 0.8833633387, 0.8862225301, 0.8890483559, 0.8918407094, + 0.8945994856, 0.8973245807, 0.9000158920, 0.9026733182, 0.9052967593, 0.9078861165, + 0.9104412923, 0.9129621904, 0.9154487161, 0.9179007756, 0.9203182767, 0.9227011283, + 0.9250492408, 0.9273625257, 0.9296408958, 0.9318842656, 0.9340925504, 0.9362656672, + 0.9384035341, 0.9405060706, 0.9425731976, 0.9446048373, 0.9466009131, 0.9485613499, + 0.9504860739, 0.9523750127, 0.9542280951, 0.9560452513, 0.9578264130, 0.9595715131, + 0.9612804858, 0.9629532669, 0.9645897933, 0.9661900034, 0.9677538371, 0.9692812354, + 0.9707721407, 0.9722264971, 0.9736442497, 0.9750253451, 0.9763697313, 0.9776773578, + 0.9789481753, 0.9801821360, 0.9813791933, 0.9825393023, 0.9836624192, 0.9847485018, + 0.9857975092, 0.9868094018, 0.9877841416, 0.9887216920, 0.9896220175, 0.9904850843, + 0.9913108598, 0.9920993131, 0.9928504145, 0.9935641355, 0.9942404495, 0.9948793308, + 0.9954807555, 0.9960447009, 0.9965711458, 0.9970600703, 0.9975114561, 0.9979252862, + 0.9983015449, 0.9986402182, 0.9989412932, 0.9992047586, 0.9994306046, 0.9996188225, + 0.9997694054, 0.9998823475, 0.9999576446, 0.9999952938}; +const FLOAT64 iusace_sine_win_128[128] = { + 0.0061358846, 0.0184067299, 0.0306748032, 0.0429382569, 0.0551952443, 0.0674439196, + 0.0796824380, 0.0919089565, 0.1041216339, 0.1163186309, 0.1284981108, 0.1406582393, + 0.1527971853, 0.1649131205, 0.1770042204, 0.1890686641, 0.2011046348, 0.2131103199, + 0.2250839114, 0.2370236060, 0.2489276057, 0.2607941179, 0.2726213554, 0.2844075372, + 0.2961508882, 0.3078496400, 0.3195020308, 0.3311063058, 0.3426607173, 0.3541635254, + 0.3656129978, 0.3770074102, 0.3883450467, 0.3996241998, 0.4108431711, 0.4220002708, + 0.4330938189, 0.4441221446, 0.4550835871, 0.4659764958, 0.4767992301, 0.4875501601, + 0.4982276670, 0.5088301425, 0.5193559902, 0.5298036247, 0.5401714727, 0.5504579729, + 0.5606615762, 0.5707807459, 0.5808139581, 0.5907597019, 0.6006164794, 0.6103828063, + 0.6200572118, 0.6296382389, 0.6391244449, 0.6485144010, 0.6578066933, 0.6669999223, + 0.6760927036, 0.6850836678, 0.6939714609, 0.7027547445, 0.7114321957, 0.7200025080, + 0.7284643904, 0.7368165689, 0.7450577854, 0.7531867990, 0.7612023855, 0.7691033376, + 0.7768884657, 0.7845565972, 0.7921065773, 0.7995372691, 0.8068475535, 0.8140363297, + 0.8211025150, 0.8280450453, 0.8348628750, 0.8415549774, 0.8481203448, 0.8545579884, + 0.8608669386, 0.8670462455, 0.8730949784, 0.8790122264, 0.8847970984, 0.8904487232, + 0.8959662498, 0.9013488470, 0.9065957045, 0.9117060320, 0.9166790599, 0.9215140393, + 0.9262102421, 0.9307669611, 0.9351835099, 0.9394592236, 0.9435934582, 0.9475855910, + 0.9514350210, 0.9551411683, 0.9587034749, 0.9621214043, 0.9653944417, 0.9685220943, + 0.9715038910, 0.9743393828, 0.9770281427, 0.9795697657, 0.9819638691, 0.9842100924, + 0.9863080972, 0.9882575677, 0.9900582103, 0.9917097537, 0.9932119492, 0.9945645707, + 0.9957674145, 0.9968202993, 0.9977230666, 0.9984755806, 0.9990777278, 0.9995294175, + 0.9998305818, 0.9999811753}; + +const FLOAT64 iexheaac_sine_win_192[192] = { + 0.004091, 0.012272, 0.020452, 0.028630, 0.036807, 0.044982, 0.053153, 0.061321, 0.069484, + 0.077643, 0.085797, 0.093945, 0.102087, 0.110222, 0.118350, 0.126469, 0.134581, 0.142683, + 0.150776, 0.158858, 0.166930, 0.174991, 0.183040, 0.191077, 0.199101, 0.207111, 0.215108, + 0.223091, 0.231058, 0.239010, 0.246946, 0.254866, 0.262768, 0.270653, 0.278520, 0.286368, + 0.294197, 0.302006, 0.309795, 0.317563, 0.325310, 0.333036, 0.340739, 0.348419, 0.356076, + 0.363709, 0.371317, 0.378901, 0.386459, 0.393992, 0.401498, 0.408978, 0.416430, 0.423854, + 0.431249, 0.438616, 0.445954, 0.453261, 0.460539, 0.467785, 0.475000, 0.482184, 0.489335, + 0.496453, 0.503538, 0.510590, 0.517607, 0.524590, 0.531537, 0.538449, 0.545325, 0.552164, + 0.558967, 0.565732, 0.572459, 0.579148, 0.585798, 0.592409, 0.598980, 0.605511, 0.612002, + 0.618451, 0.624859, 0.631226, 0.637550, 0.643832, 0.650070, 0.656265, 0.662416, 0.668522, + 0.674584, 0.680601, 0.686572, 0.692497, 0.698376, 0.704208, 0.709993, 0.715731, 0.721420, + 0.727062, 0.732654, 0.738198, 0.743692, 0.749136, 0.754531, 0.759874, 0.765167, 0.770409, + 0.775599, 0.780737, 0.785823, 0.790857, 0.795837, 0.800764, 0.805638, 0.810457, 0.815223, + 0.819933, 0.824589, 0.829190, 0.833735, 0.838225, 0.842658, 0.847035, 0.851355, 0.855618, + 0.859824, 0.863973, 0.868063, 0.872096, 0.876070, 0.879986, 0.883842, 0.887640, 0.891378, + 0.895056, 0.898674, 0.902233, 0.905731, 0.909168, 0.912544, 0.915860, 0.919114, 0.922306, + 0.925437, 0.928506, 0.931513, 0.934457, 0.937339, 0.940158, 0.942914, 0.945607, 0.948237, + 0.950803, 0.953306, 0.955745, 0.958120, 0.960431, 0.962677, 0.964859, 0.966976, 0.969029, + 0.971017, 0.972940, 0.974798, 0.976590, 0.978317, 0.979979, 0.981575, 0.983105, 0.984570, + 0.985969, 0.987301, 0.988568, 0.989768, 0.990903, 0.991970, 0.992972, 0.993907, 0.994775, + 0.995577, 0.996313, 0.996981, 0.997583, 0.998118, 0.998586, 0.998988, 0.999322, 0.999590, + 0.999791, 0.999925, 0.999992}; + +const FLOAT64 iexheaac_sine_win_96[96] = { + 0.00818113960393713, 0.02454122852291229, 0.04089474716158345, 0.05723731728756862, + 0.07356456359966743, 0.08987211489923495, 0.10615560526045749, 0.12241067519921618, + 0.13863297284022669, 0.15481815508214103, 0.17096188876030122, 0.18705985180683196, + 0.20310773440776289, 0.21910124015686980, 0.23503608720592670, 0.25090800941106001, + 0.26671275747489842, 0.28244610008421250, 0.29810382504273980, 0.31368174039889146, + 0.32917567556803889, 0.34458148244908043, 0.35989503653498817, 0.37511223801703802, + 0.39022901288242801, 0.40524131400498981, 0.42014512222870243, 0.43493644744371712, + 0.44961132965460654, 0.46416584004055156, 0.47859608200718079, 0.49289819222978404, + 0.50706834168761705, 0.52110273668902340, 0.53499761988709715, 0.54874927128561590, + 0.56235400923497303, 0.57580819141784534, 0.58910821582432815, 0.60225052171628191, + 0.61523159058062682, 0.62804794707133427, 0.64069615993986084, 0.65317284295377664, + 0.66547465580334220, 0.67759830499578866, 0.68954054473706683, 0.70129817780082437, + 0.71286805638437978, 0.72424708295146689, 0.73543221106151868, 0.74642044618527381, + 0.75720884650648457, 0.76779452370951196, 0.77817464375259782, 0.78834642762660623, + 0.79830715209903147, 0.80805415044307316, 0.81758481315158371, 0.82689658863569615, + 0.83598698390794668, 0.84485356524970701, 0.85349395886275037, 0.86190585150477428, + 0.87008699110871135, 0.87803518738566277, 0.88574831241129048, 0.89322430119551532, + 0.90046115223536360, 0.90745692805081868, 0.91420975570353058, 0.92071782729824758, + 0.92697940046683291, 0.93299279883473896, 0.93875641246981323, 0.94426869831331650, + 0.94952818059303667, 0.95453345121838840, 0.95928317015739362, 0.96377606579543984, + 0.96801093527572268, 0.97198664482127939, 0.97570213003852846, 0.97915639620223371, + 0.98234851852181571, 0.98527764238894122, 0.98794298360632238, 0.99034382859766479, + 0.99247953459870997, 0.99434952982931812, 0.99595331364654771, 0.99729045667869021, + 0.99836060094022250, 0.99916345992764877, 0.99969881869620425, 0.99996653391740109, +}; + +/* Arithmetic coding tables */ +const UWORD16 iusace_ari_cf_r[3][4] = { + {12571, 10569, 3696, 0}, {12661, 5700, 3751, 0}, {10827, 6884, 2929, 0}}; + +const UWORD16 iusace_ari_lookup_m[742] = { + 0x01, 0x34, 0x0D, 0x13, 0x12, 0x25, 0x00, 0x3A, 0x05, 0x00, 0x21, 0x13, 0x1F, 0x1A, 0x1D, + 0x36, 0x24, 0x2B, 0x1B, 0x33, 0x37, 0x29, 0x1D, 0x33, 0x37, 0x33, 0x37, 0x33, 0x37, 0x33, + 0x2C, 0x00, 0x21, 0x13, 0x25, 0x2A, 0x00, 0x21, 0x24, 0x12, 0x2C, 0x1E, 0x37, 0x24, 0x1F, + 0x35, 0x37, 0x24, 0x35, 0x37, 0x35, 0x37, 0x38, 0x2D, 0x21, 0x29, 0x1E, 0x21, 0x13, 0x2D, + 0x36, 0x38, 0x29, 0x36, 0x37, 0x24, 0x36, 0x38, 0x37, 0x38, 0x00, 0x20, 0x23, 0x20, 0x23, + 0x36, 0x38, 0x24, 0x3B, 0x24, 0x26, 0x29, 0x1F, 0x30, 0x2D, 0x0D, 0x12, 0x3F, 0x2D, 0x21, + 0x1C, 0x2A, 0x00, 0x21, 0x12, 0x1E, 0x36, 0x38, 0x36, 0x37, 0x3F, 0x1E, 0x0D, 0x1F, 0x2A, + 0x1E, 0x21, 0x24, 0x12, 0x2A, 0x3C, 0x21, 0x24, 0x1F, 0x3C, 0x21, 0x29, 0x36, 0x38, 0x36, + 0x37, 0x38, 0x21, 0x1E, 0x00, 0x3B, 0x25, 0x1E, 0x20, 0x10, 0x1F, 0x3C, 0x20, 0x23, 0x29, + 0x08, 0x23, 0x12, 0x08, 0x23, 0x21, 0x38, 0x00, 0x20, 0x13, 0x20, 0x3B, 0x1C, 0x20, 0x3B, + 0x29, 0x20, 0x23, 0x24, 0x21, 0x24, 0x21, 0x24, 0x3B, 0x13, 0x23, 0x26, 0x23, 0x13, 0x21, + 0x24, 0x26, 0x29, 0x12, 0x22, 0x2B, 0x02, 0x1E, 0x0D, 0x1F, 0x2D, 0x00, 0x0D, 0x12, 0x00, + 0x3C, 0x21, 0x29, 0x3C, 0x21, 0x2A, 0x3C, 0x3B, 0x22, 0x1E, 0x20, 0x10, 0x1F, 0x3C, 0x0D, + 0x29, 0x3C, 0x21, 0x24, 0x08, 0x23, 0x20, 0x38, 0x39, 0x3C, 0x20, 0x13, 0x3C, 0x00, 0x0D, + 0x13, 0x1F, 0x3C, 0x09, 0x26, 0x1F, 0x08, 0x09, 0x26, 0x12, 0x08, 0x23, 0x29, 0x20, 0x23, + 0x21, 0x24, 0x20, 0x13, 0x20, 0x3B, 0x16, 0x20, 0x3B, 0x29, 0x20, 0x3B, 0x29, 0x20, 0x3B, + 0x13, 0x21, 0x24, 0x29, 0x0B, 0x13, 0x09, 0x3B, 0x13, 0x09, 0x3B, 0x13, 0x21, 0x3B, 0x13, + 0x0D, 0x26, 0x29, 0x26, 0x29, 0x3D, 0x12, 0x22, 0x28, 0x2E, 0x04, 0x08, 0x13, 0x3C, 0x3B, + 0x3C, 0x20, 0x10, 0x3C, 0x21, 0x07, 0x08, 0x10, 0x00, 0x08, 0x0D, 0x29, 0x08, 0x0D, 0x29, + 0x08, 0x09, 0x13, 0x20, 0x23, 0x39, 0x08, 0x09, 0x13, 0x08, 0x09, 0x16, 0x08, 0x09, 0x10, + 0x12, 0x20, 0x3B, 0x3D, 0x09, 0x26, 0x20, 0x3B, 0x24, 0x39, 0x09, 0x26, 0x20, 0x0D, 0x13, + 0x00, 0x09, 0x13, 0x20, 0x0D, 0x26, 0x12, 0x20, 0x3B, 0x13, 0x21, 0x26, 0x0B, 0x12, 0x09, + 0x3B, 0x16, 0x09, 0x3B, 0x3D, 0x09, 0x26, 0x0D, 0x13, 0x26, 0x3D, 0x1C, 0x12, 0x1F, 0x28, + 0x2E, 0x07, 0x0B, 0x08, 0x09, 0x00, 0x39, 0x0B, 0x08, 0x26, 0x08, 0x09, 0x13, 0x20, 0x0B, + 0x39, 0x10, 0x39, 0x0D, 0x13, 0x20, 0x10, 0x12, 0x09, 0x13, 0x20, 0x3B, 0x13, 0x09, 0x26, + 0x0B, 0x09, 0x3B, 0x1C, 0x09, 0x3B, 0x13, 0x20, 0x3B, 0x13, 0x09, 0x26, 0x0B, 0x16, 0x0D, + 0x13, 0x09, 0x13, 0x09, 0x13, 0x26, 0x3D, 0x1C, 0x1F, 0x28, 0x2E, 0x07, 0x10, 0x39, 0x0B, + 0x39, 0x39, 0x13, 0x39, 0x0B, 0x39, 0x0B, 0x39, 0x26, 0x39, 0x10, 0x20, 0x3B, 0x16, 0x20, + 0x10, 0x09, 0x26, 0x0B, 0x13, 0x09, 0x13, 0x26, 0x1C, 0x0B, 0x3D, 0x1C, 0x1F, 0x28, 0x2B, + 0x07, 0x0C, 0x39, 0x0B, 0x39, 0x0B, 0x0C, 0x0B, 0x26, 0x0B, 0x26, 0x3D, 0x0D, 0x1C, 0x14, + 0x28, 0x2B, 0x39, 0x0B, 0x0C, 0x0E, 0x3D, 0x1C, 0x0D, 0x12, 0x22, 0x2B, 0x07, 0x0C, 0x0E, + 0x3D, 0x1C, 0x10, 0x1F, 0x2B, 0x0C, 0x0E, 0x19, 0x14, 0x10, 0x1F, 0x28, 0x0C, 0x0E, 0x19, + 0x14, 0x26, 0x22, 0x2B, 0x0C, 0x0E, 0x19, 0x14, 0x26, 0x28, 0x0E, 0x19, 0x14, 0x26, 0x28, + 0x0E, 0x19, 0x14, 0x28, 0x0E, 0x19, 0x14, 0x22, 0x28, 0x2B, 0x0E, 0x14, 0x2B, 0x31, 0x00, + 0x3A, 0x3A, 0x05, 0x05, 0x1B, 0x1D, 0x33, 0x06, 0x35, 0x35, 0x20, 0x21, 0x37, 0x21, 0x24, + 0x05, 0x1B, 0x2C, 0x2C, 0x2C, 0x06, 0x34, 0x1E, 0x34, 0x00, 0x08, 0x36, 0x09, 0x21, 0x26, + 0x1C, 0x2C, 0x00, 0x02, 0x02, 0x02, 0x3F, 0x04, 0x04, 0x04, 0x34, 0x39, 0x20, 0x0A, 0x0C, + 0x39, 0x0B, 0x0F, 0x07, 0x07, 0x07, 0x07, 0x34, 0x39, 0x39, 0x0A, 0x0C, 0x39, 0x0C, 0x0F, + 0x07, 0x07, 0x07, 0x00, 0x39, 0x39, 0x0C, 0x0F, 0x07, 0x07, 0x39, 0x0C, 0x0F, 0x07, 0x39, + 0x0C, 0x0F, 0x39, 0x39, 0x0C, 0x0F, 0x39, 0x0C, 0x39, 0x0C, 0x0F, 0x00, 0x11, 0x27, 0x17, + 0x2F, 0x27, 0x00, 0x27, 0x17, 0x00, 0x11, 0x17, 0x00, 0x11, 0x17, 0x11, 0x00, 0x27, 0x15, + 0x11, 0x17, 0x01, 0x15, 0x11, 0x15, 0x11, 0x15, 0x15, 0x17, 0x00, 0x27, 0x01, 0x27, 0x27, + 0x15, 0x00, 0x27, 0x11, 0x27, 0x15, 0x15, 0x15, 0x27, 0x15, 0x15, 0x15, 0x15, 0x17, 0x2F, + 0x11, 0x17, 0x27, 0x27, 0x27, 0x11, 0x27, 0x15, 0x27, 0x27, 0x15, 0x15, 0x27, 0x17, 0x2F, + 0x27, 0x17, 0x2F, 0x27, 0x17, 0x2F, 0x27, 0x17, 0x2F, 0x27, 0x17, 0x2F, 0x27, 0x17, 0x2F, + 0x27, 0x17, 0x2F, 0x27, 0x17, 0x2F, 0x27, 0x17, 0x2F, 0x27, 0x17, 0x2F, 0x27, 0x17, 0x2F, + 0x27, 0x17, 0x2F, 0x27, 0x17, 0x2F, 0x17, 0x2F, 0x2B, 0x00, 0x27, 0x00, 0x00, 0x11, 0x15, + 0x00, 0x11, 0x11, 0x27, 0x27, 0x15, 0x17, 0x15, 0x17, 0x15, 0x17, 0x27, 0x17, 0x27, 0x17, + 0x27, 0x17, 0x27, 0x17, 0x27, 0x17, 0x27, 0x17, 0x27, 0x17, 0x27, 0x17, 0x27, 0x17, 0x27, + 0x17, 0x27, 0x15, 0x27, 0x27, 0x15, 0x27}; + +const UWORD32 iusace_ari_hash_m[742] = { + 0x00000104UL >> 8, 0x0000030AUL >> 8, 0x00000510UL >> 8, 0x00000716UL >> 8, 0x00000A1FUL >> 8, + 0x00000F2EUL >> 8, 0x00011100UL >> 8, 0x00111103UL >> 8, 0x00111306UL >> 8, 0x00111436UL >> 8, + 0x00111623UL >> 8, 0x00111929UL >> 8, 0x00111F2EUL >> 8, 0x0011221BUL >> 8, 0x00112435UL >> 8, + 0x00112621UL >> 8, 0x00112D12UL >> 8, 0x00113130UL >> 8, 0x0011331DUL >> 8, 0x00113535UL >> 8, + 0x00113938UL >> 8, 0x0011411BUL >> 8, 0x00114433UL >> 8, 0x00114635UL >> 8, 0x00114F29UL >> 8, + 0x00116635UL >> 8, 0x00116F24UL >> 8, 0x00117433UL >> 8, 0x0011FF0FUL >> 8, 0x00121102UL >> 8, + 0x0012132DUL >> 8, 0x00121436UL >> 8, 0x00121623UL >> 8, 0x00121912UL >> 8, 0x0012213FUL >> 8, + 0x0012232DUL >> 8, 0x00122436UL >> 8, 0x00122638UL >> 8, 0x00122A29UL >> 8, 0x00122F2BUL >> 8, + 0x0012322DUL >> 8, 0x00123436UL >> 8, 0x00123738UL >> 8, 0x00123B29UL >> 8, 0x0012411DUL >> 8, + 0x00124536UL >> 8, 0x00124938UL >> 8, 0x00124F12UL >> 8, 0x00125535UL >> 8, 0x00125F29UL >> 8, + 0x00126535UL >> 8, 0x0012B837UL >> 8, 0x0013112AUL >> 8, 0x0013131EUL >> 8, 0x0013163BUL >> 8, + 0x0013212DUL >> 8, 0x0013233CUL >> 8, 0x00132623UL >> 8, 0x00132F2EUL >> 8, 0x0013321EUL >> 8, + 0x00133521UL >> 8, 0x00133824UL >> 8, 0x0013411EUL >> 8, 0x00134336UL >> 8, 0x00134838UL >> 8, + 0x00135135UL >> 8, 0x00135537UL >> 8, 0x00135F12UL >> 8, 0x00137637UL >> 8, 0x0013FF29UL >> 8, + 0x00140024UL >> 8, 0x00142321UL >> 8, 0x00143136UL >> 8, 0x00143321UL >> 8, 0x00143F25UL >> 8, + 0x00144321UL >> 8, 0x00148638UL >> 8, 0x0014FF29UL >> 8, 0x00154323UL >> 8, 0x0015FF12UL >> 8, + 0x0016F20CUL >> 8, 0x0018A529UL >> 8, 0x00210031UL >> 8, 0x0021122CUL >> 8, 0x00211408UL >> 8, + 0x00211713UL >> 8, 0x00211F2EUL >> 8, 0x0021222AUL >> 8, 0x00212408UL >> 8, 0x00212710UL >> 8, + 0x00212F2EUL >> 8, 0x0021331EUL >> 8, 0x00213436UL >> 8, 0x00213824UL >> 8, 0x0021412DUL >> 8, + 0x0021431EUL >> 8, 0x00214536UL >> 8, 0x00214F1FUL >> 8, 0x00216637UL >> 8, 0x00220004UL >> 8, + 0x0022122AUL >> 8, 0x00221420UL >> 8, 0x00221829UL >> 8, 0x00221F2EUL >> 8, 0x0022222DUL >> 8, + 0x00222408UL >> 8, 0x00222623UL >> 8, 0x00222929UL >> 8, 0x00222F2BUL >> 8, 0x0022321EUL >> 8, + 0x00223408UL >> 8, 0x00223724UL >> 8, 0x00223A29UL >> 8, 0x0022411EUL >> 8, 0x00224436UL >> 8, + 0x00224823UL >> 8, 0x00225134UL >> 8, 0x00225621UL >> 8, 0x00225F12UL >> 8, 0x00226336UL >> 8, + 0x00227637UL >> 8, 0x0022FF29UL >> 8, 0x0023112DUL >> 8, 0x0023133CUL >> 8, 0x00231420UL >> 8, + 0x00231916UL >> 8, 0x0023212DUL >> 8, 0x0023233CUL >> 8, 0x00232509UL >> 8, 0x00232929UL >> 8, + 0x0023312DUL >> 8, 0x00233308UL >> 8, 0x00233509UL >> 8, 0x00233724UL >> 8, 0x0023413CUL >> 8, + 0x00234421UL >> 8, 0x00234A13UL >> 8, 0x0023513CUL >> 8, 0x00235421UL >> 8, 0x00235F1FUL >> 8, + 0x00236421UL >> 8, 0x0023FF29UL >> 8, 0x00240024UL >> 8, 0x0024153BUL >> 8, 0x00242108UL >> 8, + 0x00242409UL >> 8, 0x00242726UL >> 8, 0x00243108UL >> 8, 0x00243409UL >> 8, 0x00243610UL >> 8, + 0x00244136UL >> 8, 0x00244321UL >> 8, 0x00244523UL >> 8, 0x00244F1FUL >> 8, 0x00245423UL >> 8, + 0x0024610AUL >> 8, 0x00246423UL >> 8, 0x0024FF29UL >> 8, 0x00252510UL >> 8, 0x00253121UL >> 8, + 0x0025343BUL >> 8, 0x00254121UL >> 8, 0x00254510UL >> 8, 0x00254F25UL >> 8, 0x00255221UL >> 8, + 0x0025FF12UL >> 8, 0x00266513UL >> 8, 0x0027F529UL >> 8, 0x0029F101UL >> 8, 0x002CF224UL >> 8, + 0x00310030UL >> 8, 0x0031122AUL >> 8, 0x00311420UL >> 8, 0x00311816UL >> 8, 0x0031212CUL >> 8, + 0x0031231EUL >> 8, 0x00312408UL >> 8, 0x00312710UL >> 8, 0x0031312AUL >> 8, 0x0031321EUL >> 8, + 0x00313408UL >> 8, 0x00313623UL >> 8, 0x0031411EUL >> 8, 0x0031433CUL >> 8, 0x00320007UL >> 8, + 0x0032122DUL >> 8, 0x00321420UL >> 8, 0x00321816UL >> 8, 0x0032212DUL >> 8, 0x0032233CUL >> 8, + 0x00322509UL >> 8, 0x00322916UL >> 8, 0x0032312DUL >> 8, 0x00323420UL >> 8, 0x00323710UL >> 8, + 0x00323F2BUL >> 8, 0x00324308UL >> 8, 0x00324623UL >> 8, 0x00324F25UL >> 8, 0x00325421UL >> 8, + 0x00325F1FUL >> 8, 0x00326421UL >> 8, 0x0032FF29UL >> 8, 0x00331107UL >> 8, 0x00331308UL >> 8, + 0x0033150DUL >> 8, 0x0033211EUL >> 8, 0x00332308UL >> 8, 0x00332420UL >> 8, 0x00332610UL >> 8, + 0x00332929UL >> 8, 0x0033311EUL >> 8, 0x00333308UL >> 8, 0x0033363BUL >> 8, 0x00333A29UL >> 8, + 0x0033413CUL >> 8, 0x00334320UL >> 8, 0x0033463BUL >> 8, 0x00334A29UL >> 8, 0x0033510AUL >> 8, + 0x00335320UL >> 8, 0x00335824UL >> 8, 0x0033610AUL >> 8, 0x00336321UL >> 8, 0x00336F12UL >> 8, + 0x00337623UL >> 8, 0x00341139UL >> 8, 0x0034153BUL >> 8, 0x00342108UL >> 8, 0x00342409UL >> 8, + 0x00342610UL >> 8, 0x00343108UL >> 8, 0x00343409UL >> 8, 0x00343610UL >> 8, 0x00344108UL >> 8, + 0x0034440DUL >> 8, 0x00344610UL >> 8, 0x0034510AUL >> 8, 0x00345309UL >> 8, 0x0034553BUL >> 8, + 0x0034610AUL >> 8, 0x00346309UL >> 8, 0x0034F824UL >> 8, 0x00350029UL >> 8, 0x00352510UL >> 8, + 0x00353120UL >> 8, 0x0035330DUL >> 8, 0x00353510UL >> 8, 0x00354120UL >> 8, 0x0035430DUL >> 8, + 0x00354510UL >> 8, 0x00354F28UL >> 8, 0x0035530DUL >> 8, 0x00355510UL >> 8, 0x00355F1FUL >> 8, + 0x00356410UL >> 8, 0x00359626UL >> 8, 0x0035FF12UL >> 8, 0x00366426UL >> 8, 0x0036FF12UL >> 8, + 0x0037F426UL >> 8, 0x0039D712UL >> 8, 0x003BF612UL >> 8, 0x003DF81FUL >> 8, 0x00410004UL >> 8, + 0x00411207UL >> 8, 0x0041150DUL >> 8, 0x0041212AUL >> 8, 0x00412420UL >> 8, 0x0041311EUL >> 8, + 0x00413308UL >> 8, 0x00413509UL >> 8, 0x00413F2BUL >> 8, 0x00414208UL >> 8, 0x00420007UL >> 8, + 0x0042123CUL >> 8, 0x00421409UL >> 8, 0x00422107UL >> 8, 0x0042223CUL >> 8, 0x00422409UL >> 8, + 0x00422610UL >> 8, 0x0042313CUL >> 8, 0x00423409UL >> 8, 0x0042363BUL >> 8, 0x0042413CUL >> 8, + 0x00424320UL >> 8, 0x0042463BUL >> 8, 0x00425108UL >> 8, 0x00425409UL >> 8, 0x0042FF29UL >> 8, + 0x00431107UL >> 8, 0x00431320UL >> 8, 0x0043153BUL >> 8, 0x0043213CUL >> 8, 0x00432320UL >> 8, + 0x00432610UL >> 8, 0x0043313CUL >> 8, 0x00433320UL >> 8, 0x0043353BUL >> 8, 0x00433813UL >> 8, + 0x00434108UL >> 8, 0x00434409UL >> 8, 0x00434610UL >> 8, 0x00435108UL >> 8, 0x0043553BUL >> 8, + 0x00435F25UL >> 8, 0x00436309UL >> 8, 0x0043753BUL >> 8, 0x0043FF29UL >> 8, 0x00441239UL >> 8, + 0x0044143BUL >> 8, 0x00442139UL >> 8, 0x00442309UL >> 8, 0x0044253BUL >> 8, 0x00443108UL >> 8, + 0x00443220UL >> 8, 0x0044353BUL >> 8, 0x0044410AUL >> 8, 0x00444309UL >> 8, 0x0044453BUL >> 8, + 0x00444813UL >> 8, 0x0044510AUL >> 8, 0x00445309UL >> 8, 0x00445510UL >> 8, 0x00445F25UL >> 8, + 0x0044630DUL >> 8, 0x00450026UL >> 8, 0x00452713UL >> 8, 0x00453120UL >> 8, 0x0045330DUL >> 8, + 0x00453510UL >> 8, 0x00454120UL >> 8, 0x0045430DUL >> 8, 0x00454510UL >> 8, 0x00455120UL >> 8, + 0x0045530DUL >> 8, 0x00456209UL >> 8, 0x00456410UL >> 8, 0x0045FF12UL >> 8, 0x00466513UL >> 8, + 0x0047FF22UL >> 8, 0x0048FF25UL >> 8, 0x0049F43DUL >> 8, 0x004BFB25UL >> 8, 0x004EF825UL >> 8, + 0x004FFF18UL >> 8, 0x00511339UL >> 8, 0x00512107UL >> 8, 0x00513409UL >> 8, 0x00520007UL >> 8, + 0x00521107UL >> 8, 0x00521320UL >> 8, 0x00522107UL >> 8, 0x00522409UL >> 8, 0x0052313CUL >> 8, + 0x00523320UL >> 8, 0x0052353BUL >> 8, 0x00524108UL >> 8, 0x00524320UL >> 8, 0x00531139UL >> 8, + 0x00531309UL >> 8, 0x00532139UL >> 8, 0x00532309UL >> 8, 0x0053253BUL >> 8, 0x00533108UL >> 8, + 0x0053340DUL >> 8, 0x00533713UL >> 8, 0x00534108UL >> 8, 0x0053453BUL >> 8, 0x00534F2BUL >> 8, + 0x00535309UL >> 8, 0x00535610UL >> 8, 0x00535F25UL >> 8, 0x0053643BUL >> 8, 0x00541139UL >> 8, + 0x00542139UL >> 8, 0x00542309UL >> 8, 0x00542613UL >> 8, 0x00543139UL >> 8, 0x00543309UL >> 8, + 0x00543510UL >> 8, 0x00543F2BUL >> 8, 0x00544309UL >> 8, 0x00544510UL >> 8, 0x00544F28UL >> 8, + 0x0054530DUL >> 8, 0x0054FF12UL >> 8, 0x00553613UL >> 8, 0x00553F2BUL >> 8, 0x00554410UL >> 8, + 0x0055510AUL >> 8, 0x0055543BUL >> 8, 0x00555F25UL >> 8, 0x0055633BUL >> 8, 0x0055FF12UL >> 8, + 0x00566513UL >> 8, 0x00577413UL >> 8, 0x0059FF28UL >> 8, 0x005CC33DUL >> 8, 0x005EFB28UL >> 8, + 0x005FFF18UL >> 8, 0x00611339UL >> 8, 0x00612107UL >> 8, 0x00613320UL >> 8, 0x0061A724UL >> 8, + 0x00621107UL >> 8, 0x0062140BUL >> 8, 0x00622107UL >> 8, 0x00622320UL >> 8, 0x00623139UL >> 8, + 0x00623320UL >> 8, 0x00631139UL >> 8, 0x0063130CUL >> 8, 0x00632139UL >> 8, 0x00632309UL >> 8, + 0x00633139UL >> 8, 0x00633309UL >> 8, 0x00633626UL >> 8, 0x00633F2BUL >> 8, 0x00634309UL >> 8, + 0x00634F2BUL >> 8, 0x0063543BUL >> 8, 0x0063FF12UL >> 8, 0x0064343BUL >> 8, 0x00643F2BUL >> 8, + 0x0064443BUL >> 8, 0x00645209UL >> 8, 0x00665513UL >> 8, 0x0066610AUL >> 8, 0x00666526UL >> 8, + 0x0067A616UL >> 8, 0x0069843DUL >> 8, 0x006CF612UL >> 8, 0x006EF326UL >> 8, 0x006FFF18UL >> 8, + 0x0071130CUL >> 8, 0x00721107UL >> 8, 0x00722239UL >> 8, 0x0072291CUL >> 8, 0x0072340BUL >> 8, + 0x00731139UL >> 8, 0x00732239UL >> 8, 0x0073630BUL >> 8, 0x0073FF12UL >> 8, 0x0074430BUL >> 8, + 0x00755426UL >> 8, 0x00776F28UL >> 8, 0x00777410UL >> 8, 0x0078843DUL >> 8, 0x007CF416UL >> 8, + 0x007EF326UL >> 8, 0x007FFF18UL >> 8, 0x00822239UL >> 8, 0x00831139UL >> 8, 0x0083430BUL >> 8, + 0x0084530BUL >> 8, 0x0087561CUL >> 8, 0x00887F25UL >> 8, 0x00888426UL >> 8, 0x008AF61CUL >> 8, + 0x008F0018UL >> 8, 0x008FFF18UL >> 8, 0x00911107UL >> 8, 0x0093230BUL >> 8, 0x0094530BUL >> 8, + 0x0097743DUL >> 8, 0x00998C25UL >> 8, 0x00999616UL >> 8, 0x009EF825UL >> 8, 0x009FFF18UL >> 8, + 0x00A3430BUL >> 8, 0x00A4530BUL >> 8, 0x00A7743DUL >> 8, 0x00AA9F2BUL >> 8, 0x00AAA616UL >> 8, + 0x00ABD61FUL >> 8, 0x00AFFF18UL >> 8, 0x00B3330BUL >> 8, 0x00B44426UL >> 8, 0x00B7643DUL >> 8, + 0x00BB971FUL >> 8, 0x00BBB53DUL >> 8, 0x00BEF512UL >> 8, 0x00BFFF18UL >> 8, 0x00C22139UL >> 8, + 0x00C5330EUL >> 8, 0x00C7633DUL >> 8, 0x00CCAF2EUL >> 8, 0x00CCC616UL >> 8, 0x00CFFF18UL >> 8, + 0x00D4440EUL >> 8, 0x00D6420EUL >> 8, 0x00DDCF2EUL >> 8, 0x00DDD516UL >> 8, 0x00DFFF18UL >> 8, + 0x00E4330EUL >> 8, 0x00E6841CUL >> 8, 0x00EEE61CUL >> 8, 0x00EFFF18UL >> 8, 0x00F3320EUL >> 8, + 0x00F55319UL >> 8, 0x00F8F41CUL >> 8, 0x00FAFF2EUL >> 8, 0x00FF002EUL >> 8, 0x00FFF10CUL >> 8, + 0x00FFF33DUL >> 8, 0x00FFF722UL >> 8, 0x00FFFF18UL >> 8, 0x01000232UL >> 8, 0x0111113EUL >> 8, + 0x01112103UL >> 8, 0x0111311AUL >> 8, 0x0112111AUL >> 8, 0x01122130UL >> 8, 0x01123130UL >> 8, + 0x0112411DUL >> 8, 0x01131102UL >> 8, 0x01132102UL >> 8, 0x01133102UL >> 8, 0x01141108UL >> 8, + 0x01142136UL >> 8, 0x01143136UL >> 8, 0x01144135UL >> 8, 0x0115223BUL >> 8, 0x01211103UL >> 8, + 0x0121211AUL >> 8, 0x01213130UL >> 8, 0x01221130UL >> 8, 0x01222130UL >> 8, 0x01223102UL >> 8, + 0x01231104UL >> 8, 0x01232104UL >> 8, 0x01233104UL >> 8, 0x01241139UL >> 8, 0x01241220UL >> 8, + 0x01242220UL >> 8, 0x01251109UL >> 8, 0x0125223BUL >> 8, 0x0125810AUL >> 8, 0x01283212UL >> 8, + 0x0131111AUL >> 8, 0x01312130UL >> 8, 0x0131222CUL >> 8, 0x0131322AUL >> 8, 0x0132122AUL >> 8, + 0x0132222DUL >> 8, 0x0132322DUL >> 8, 0x01331207UL >> 8, 0x01332234UL >> 8, 0x01333234UL >> 8, + 0x01341139UL >> 8, 0x01343134UL >> 8, 0x01344134UL >> 8, 0x01348134UL >> 8, 0x0135220BUL >> 8, + 0x0136110BUL >> 8, 0x01365224UL >> 8, 0x01411102UL >> 8, 0x01412104UL >> 8, 0x01431239UL >> 8, + 0x01432239UL >> 8, 0x0143320AUL >> 8, 0x01435134UL >> 8, 0x01443107UL >> 8, 0x01444134UL >> 8, + 0x01446134UL >> 8, 0x0145220EUL >> 8, 0x01455134UL >> 8, 0x0147110EUL >> 8, 0x01511102UL >> 8, + 0x01521239UL >> 8, 0x01531239UL >> 8, 0x01532239UL >> 8, 0x01533107UL >> 8, 0x0155220EUL >> 8, + 0x01555134UL >> 8, 0x0157110EUL >> 8, 0x01611107UL >> 8, 0x01621239UL >> 8, 0x01631239UL >> 8, + 0x01661139UL >> 8, 0x01666134UL >> 8, 0x01711107UL >> 8, 0x01721239UL >> 8, 0x01745107UL >> 8, + 0x0177110CUL >> 8, 0x01811107UL >> 8, 0x01821107UL >> 8, 0x0185110CUL >> 8, 0x0188210CUL >> 8, + 0x01911107UL >> 8, 0x01933139UL >> 8, 0x01A11107UL >> 8, 0x01A31139UL >> 8, 0x01F5220EUL >> 8, + 0x02000001UL >> 8, 0x02000127UL >> 8, 0x02000427UL >> 8, 0x02000727UL >> 8, 0x02000E2FUL >> 8, + 0x02110000UL >> 8, 0x02111200UL >> 8, 0x02111411UL >> 8, 0x02111827UL >> 8, 0x02111F2FUL >> 8, + 0x02112411UL >> 8, 0x02112715UL >> 8, 0x02113200UL >> 8, 0x02113411UL >> 8, 0x02113715UL >> 8, + 0x02114200UL >> 8, 0x02121200UL >> 8, 0x02121301UL >> 8, 0x02121F2FUL >> 8, 0x02122200UL >> 8, + 0x02122615UL >> 8, 0x02122F2FUL >> 8, 0x02123311UL >> 8, 0x02123F2FUL >> 8, 0x02124411UL >> 8, + 0x02131211UL >> 8, 0x02132311UL >> 8, 0x02133211UL >> 8, 0x02184415UL >> 8, 0x02211200UL >> 8, + 0x02211311UL >> 8, 0x02211F2FUL >> 8, 0x02212311UL >> 8, 0x02212F2FUL >> 8, 0x02213211UL >> 8, + 0x02221201UL >> 8, 0x02221311UL >> 8, 0x02221F2FUL >> 8, 0x02222311UL >> 8, 0x02222F2FUL >> 8, + 0x02223211UL >> 8, 0x02223F2FUL >> 8, 0x02231211UL >> 8, 0x02232211UL >> 8, 0x02232F2FUL >> 8, + 0x02233211UL >> 8, 0x02233F2FUL >> 8, 0x02287515UL >> 8, 0x022DAB17UL >> 8, 0x02311211UL >> 8, + 0x02311527UL >> 8, 0x02312211UL >> 8, 0x02321211UL >> 8, 0x02322211UL >> 8, 0x02322F2FUL >> 8, + 0x02323311UL >> 8, 0x02323F2FUL >> 8, 0x02331211UL >> 8, 0x02332211UL >> 8, 0x02332F2FUL >> 8, + 0x02333F2FUL >> 8, 0x0237FF17UL >> 8, 0x02385615UL >> 8, 0x023D9517UL >> 8, 0x02410027UL >> 8, + 0x02487827UL >> 8, 0x024E3117UL >> 8, 0x024FFF2FUL >> 8, 0x02598627UL >> 8, 0x025DFF2FUL >> 8, + 0x025FFF2FUL >> 8, 0x02687827UL >> 8, 0x026DFA17UL >> 8, 0x026FFF2FUL >> 8, 0x02796427UL >> 8, + 0x027E4217UL >> 8, 0x027FFF2FUL >> 8, 0x02888727UL >> 8, 0x028EFF2FUL >> 8, 0x028FFF2FUL >> 8, + 0x02984327UL >> 8, 0x029F112FUL >> 8, 0x029FFF2FUL >> 8, 0x02A76527UL >> 8, 0x02AEF717UL >> 8, + 0x02AFFF2FUL >> 8, 0x02B7C827UL >> 8, 0x02BEF917UL >> 8, 0x02BFFF2FUL >> 8, 0x02C66527UL >> 8, + 0x02CD5517UL >> 8, 0x02CFFF2FUL >> 8, 0x02D63227UL >> 8, 0x02DDD527UL >> 8, 0x02DFFF2BUL >> 8, + 0x02E84717UL >> 8, 0x02EEE327UL >> 8, 0x02EFFF2FUL >> 8, 0x02F54527UL >> 8, 0x02FCF817UL >> 8, + 0x02FFEF2BUL >> 8, 0x02FFFA2FUL >> 8, 0x02FFFE2FUL >> 8, 0x03000127UL >> 8, 0x03000201UL >> 8, + 0x03111200UL >> 8, 0x03122115UL >> 8, 0x03123200UL >> 8, 0x03133211UL >> 8, 0x03211200UL >> 8, + 0x03213127UL >> 8, 0x03221200UL >> 8, 0x03345215UL >> 8, 0x04000F17UL >> 8, 0x04122F17UL >> 8, + 0x043F6515UL >> 8, 0x043FFF17UL >> 8, 0x044F5527UL >> 8, 0x044FFF17UL >> 8, 0x045F0017UL >> 8, + 0x045FFF17UL >> 8, 0x046F6517UL >> 8, 0x04710027UL >> 8, 0x047F4427UL >> 8, 0x04810027UL >> 8, + 0x048EFA15UL >> 8, 0x048FFF2FUL >> 8, 0x049F4427UL >> 8, 0x049FFF2FUL >> 8, 0x04AEA727UL >> 8, + 0x04AFFF2FUL >> 8, 0x04BE9C15UL >> 8, 0x04BFFF2FUL >> 8, 0x04CE5427UL >> 8, 0x04CFFF2FUL >> 8, + 0x04DE3527UL >> 8, 0x04DFFF17UL >> 8, 0x04EE4627UL >> 8, 0x04EFFF17UL >> 8, 0x04FEF327UL >> 8, + 0x04FFFF2FUL >> 8, 0x06000F27UL >> 8, 0x069FFF17UL >> 8, 0x06FFFF17UL >> 8, 0x08110017UL >> 8, + 0x08EFFF15UL >> 8, 0xFFFFFF00UL >> 8}; + +const UWORD8 iusace_ari_hash_m_lsb[742] = { + (UWORD8)0x04, (UWORD8)0x0A, (UWORD8)0x10, (UWORD8)0x16, (UWORD8)0x1F, (UWORD8)0x2E, + (UWORD8)0x00, (UWORD8)0x03, (UWORD8)0x06, (UWORD8)0x36, (UWORD8)0x23, (UWORD8)0x29, + (UWORD8)0x2E, (UWORD8)0x1B, (UWORD8)0x35, (UWORD8)0x21, (UWORD8)0x12, (UWORD8)0x30, + (UWORD8)0x1D, (UWORD8)0x35, (UWORD8)0x38, (UWORD8)0x1B, (UWORD8)0x33, (UWORD8)0x35, + (UWORD8)0x29, (UWORD8)0x35, (UWORD8)0x24, (UWORD8)0x33, (UWORD8)0x0F, (UWORD8)0x02, + (UWORD8)0x2D, (UWORD8)0x36, (UWORD8)0x23, (UWORD8)0x12, (UWORD8)0x3F, (UWORD8)0x2D, + (UWORD8)0x36, (UWORD8)0x38, (UWORD8)0x29, (UWORD8)0x2B, (UWORD8)0x2D, (UWORD8)0x36, + (UWORD8)0x38, (UWORD8)0x29, (UWORD8)0x1D, (UWORD8)0x36, (UWORD8)0x38, (UWORD8)0x12, + (UWORD8)0x35, (UWORD8)0x29, (UWORD8)0x35, (UWORD8)0x37, (UWORD8)0x2A, (UWORD8)0x1E, + (UWORD8)0x3B, (UWORD8)0x2D, (UWORD8)0x3C, (UWORD8)0x23, (UWORD8)0x2E, (UWORD8)0x1E, + (UWORD8)0x21, (UWORD8)0x24, (UWORD8)0x1E, (UWORD8)0x36, (UWORD8)0x38, (UWORD8)0x35, + (UWORD8)0x37, (UWORD8)0x12, (UWORD8)0x37, (UWORD8)0x29, (UWORD8)0x24, (UWORD8)0x21, + (UWORD8)0x36, (UWORD8)0x21, (UWORD8)0x25, (UWORD8)0x21, (UWORD8)0x38, (UWORD8)0x29, + (UWORD8)0x23, (UWORD8)0x12, (UWORD8)0x0C, (UWORD8)0x29, (UWORD8)0x31, (UWORD8)0x2C, + (UWORD8)0x08, (UWORD8)0x13, (UWORD8)0x2E, (UWORD8)0x2A, (UWORD8)0x08, (UWORD8)0x10, + (UWORD8)0x2E, (UWORD8)0x1E, (UWORD8)0x36, (UWORD8)0x24, (UWORD8)0x2D, (UWORD8)0x1E, + (UWORD8)0x36, (UWORD8)0x1F, (UWORD8)0x37, (UWORD8)0x04, (UWORD8)0x2A, (UWORD8)0x20, + (UWORD8)0x29, (UWORD8)0x2E, (UWORD8)0x2D, (UWORD8)0x08, (UWORD8)0x23, (UWORD8)0x29, + (UWORD8)0x2B, (UWORD8)0x1E, (UWORD8)0x08, (UWORD8)0x24, (UWORD8)0x29, (UWORD8)0x1E, + (UWORD8)0x36, (UWORD8)0x23, (UWORD8)0x34, (UWORD8)0x21, (UWORD8)0x12, (UWORD8)0x36, + (UWORD8)0x37, (UWORD8)0x29, (UWORD8)0x2D, (UWORD8)0x3C, (UWORD8)0x20, (UWORD8)0x16, + (UWORD8)0x2D, (UWORD8)0x3C, (UWORD8)0x09, (UWORD8)0x29, (UWORD8)0x2D, (UWORD8)0x08, + (UWORD8)0x09, (UWORD8)0x24, (UWORD8)0x3C, (UWORD8)0x21, (UWORD8)0x13, (UWORD8)0x3C, + (UWORD8)0x21, (UWORD8)0x1F, (UWORD8)0x21, (UWORD8)0x29, (UWORD8)0x24, (UWORD8)0x3B, + (UWORD8)0x08, (UWORD8)0x09, (UWORD8)0x26, (UWORD8)0x08, (UWORD8)0x09, (UWORD8)0x10, + (UWORD8)0x36, (UWORD8)0x21, (UWORD8)0x23, (UWORD8)0x1F, (UWORD8)0x23, (UWORD8)0x0A, + (UWORD8)0x23, (UWORD8)0x29, (UWORD8)0x10, (UWORD8)0x21, (UWORD8)0x3B, (UWORD8)0x21, + (UWORD8)0x10, (UWORD8)0x25, (UWORD8)0x21, (UWORD8)0x12, (UWORD8)0x13, (UWORD8)0x29, + (UWORD8)0x01, (UWORD8)0x24, (UWORD8)0x30, (UWORD8)0x2A, (UWORD8)0x20, (UWORD8)0x16, + (UWORD8)0x2C, (UWORD8)0x1E, (UWORD8)0x08, (UWORD8)0x10, (UWORD8)0x2A, (UWORD8)0x1E, + (UWORD8)0x08, (UWORD8)0x23, (UWORD8)0x1E, (UWORD8)0x3C, (UWORD8)0x07, (UWORD8)0x2D, + (UWORD8)0x20, (UWORD8)0x16, (UWORD8)0x2D, (UWORD8)0x3C, (UWORD8)0x09, (UWORD8)0x16, + (UWORD8)0x2D, (UWORD8)0x20, (UWORD8)0x10, (UWORD8)0x2B, (UWORD8)0x08, (UWORD8)0x23, + (UWORD8)0x25, (UWORD8)0x21, (UWORD8)0x1F, (UWORD8)0x21, (UWORD8)0x29, (UWORD8)0x07, + (UWORD8)0x08, (UWORD8)0x0D, (UWORD8)0x1E, (UWORD8)0x08, (UWORD8)0x20, (UWORD8)0x10, + (UWORD8)0x29, (UWORD8)0x1E, (UWORD8)0x08, (UWORD8)0x3B, (UWORD8)0x29, (UWORD8)0x3C, + (UWORD8)0x20, (UWORD8)0x3B, (UWORD8)0x29, (UWORD8)0x0A, (UWORD8)0x20, (UWORD8)0x24, + (UWORD8)0x0A, (UWORD8)0x21, (UWORD8)0x12, (UWORD8)0x23, (UWORD8)0x39, (UWORD8)0x3B, + (UWORD8)0x08, (UWORD8)0x09, (UWORD8)0x10, (UWORD8)0x08, (UWORD8)0x09, (UWORD8)0x10, + (UWORD8)0x08, (UWORD8)0x0D, (UWORD8)0x10, (UWORD8)0x0A, (UWORD8)0x09, (UWORD8)0x3B, + (UWORD8)0x0A, (UWORD8)0x09, (UWORD8)0x24, (UWORD8)0x29, (UWORD8)0x10, (UWORD8)0x20, + (UWORD8)0x0D, (UWORD8)0x10, (UWORD8)0x20, (UWORD8)0x0D, (UWORD8)0x10, (UWORD8)0x28, + (UWORD8)0x0D, (UWORD8)0x10, (UWORD8)0x1F, (UWORD8)0x10, (UWORD8)0x26, (UWORD8)0x12, + (UWORD8)0x26, (UWORD8)0x12, (UWORD8)0x26, (UWORD8)0x12, (UWORD8)0x12, (UWORD8)0x1F, + (UWORD8)0x04, (UWORD8)0x07, (UWORD8)0x0D, (UWORD8)0x2A, (UWORD8)0x20, (UWORD8)0x1E, + (UWORD8)0x08, (UWORD8)0x09, (UWORD8)0x2B, (UWORD8)0x08, (UWORD8)0x07, (UWORD8)0x3C, + (UWORD8)0x09, (UWORD8)0x07, (UWORD8)0x3C, (UWORD8)0x09, (UWORD8)0x10, (UWORD8)0x3C, + (UWORD8)0x09, (UWORD8)0x3B, (UWORD8)0x3C, (UWORD8)0x20, (UWORD8)0x3B, (UWORD8)0x08, + (UWORD8)0x09, (UWORD8)0x29, (UWORD8)0x07, (UWORD8)0x20, (UWORD8)0x3B, (UWORD8)0x3C, + (UWORD8)0x20, (UWORD8)0x10, (UWORD8)0x3C, (UWORD8)0x20, (UWORD8)0x3B, (UWORD8)0x13, + (UWORD8)0x08, (UWORD8)0x09, (UWORD8)0x10, (UWORD8)0x08, (UWORD8)0x3B, (UWORD8)0x25, + (UWORD8)0x09, (UWORD8)0x3B, (UWORD8)0x29, (UWORD8)0x39, (UWORD8)0x3B, (UWORD8)0x39, + (UWORD8)0x09, (UWORD8)0x3B, (UWORD8)0x08, (UWORD8)0x20, (UWORD8)0x3B, (UWORD8)0x0A, + (UWORD8)0x09, (UWORD8)0x3B, (UWORD8)0x13, (UWORD8)0x0A, (UWORD8)0x09, (UWORD8)0x10, + (UWORD8)0x25, (UWORD8)0x0D, (UWORD8)0x26, (UWORD8)0x13, (UWORD8)0x20, (UWORD8)0x0D, + (UWORD8)0x10, (UWORD8)0x20, (UWORD8)0x0D, (UWORD8)0x10, (UWORD8)0x20, (UWORD8)0x0D, + (UWORD8)0x09, (UWORD8)0x10, (UWORD8)0x12, (UWORD8)0x13, (UWORD8)0x22, (UWORD8)0x25, + (UWORD8)0x3D, (UWORD8)0x25, (UWORD8)0x25, (UWORD8)0x18, (UWORD8)0x39, (UWORD8)0x07, + (UWORD8)0x09, (UWORD8)0x07, (UWORD8)0x07, (UWORD8)0x20, (UWORD8)0x07, (UWORD8)0x09, + (UWORD8)0x3C, (UWORD8)0x20, (UWORD8)0x3B, (UWORD8)0x08, (UWORD8)0x20, (UWORD8)0x39, + (UWORD8)0x09, (UWORD8)0x39, (UWORD8)0x09, (UWORD8)0x3B, (UWORD8)0x08, (UWORD8)0x0D, + (UWORD8)0x13, (UWORD8)0x08, (UWORD8)0x3B, (UWORD8)0x2B, (UWORD8)0x09, (UWORD8)0x10, + (UWORD8)0x25, (UWORD8)0x3B, (UWORD8)0x39, (UWORD8)0x39, (UWORD8)0x09, (UWORD8)0x13, + (UWORD8)0x39, (UWORD8)0x09, (UWORD8)0x10, (UWORD8)0x2B, (UWORD8)0x09, (UWORD8)0x10, + (UWORD8)0x28, (UWORD8)0x0D, (UWORD8)0x12, (UWORD8)0x13, (UWORD8)0x2B, (UWORD8)0x10, + (UWORD8)0x0A, (UWORD8)0x3B, (UWORD8)0x25, (UWORD8)0x3B, (UWORD8)0x12, (UWORD8)0x13, + (UWORD8)0x13, (UWORD8)0x28, (UWORD8)0x3D, (UWORD8)0x28, (UWORD8)0x18, (UWORD8)0x39, + (UWORD8)0x07, (UWORD8)0x20, (UWORD8)0x24, (UWORD8)0x07, (UWORD8)0x0B, (UWORD8)0x07, + (UWORD8)0x20, (UWORD8)0x39, (UWORD8)0x20, (UWORD8)0x39, (UWORD8)0x0C, (UWORD8)0x39, + (UWORD8)0x09, (UWORD8)0x39, (UWORD8)0x09, (UWORD8)0x26, (UWORD8)0x2B, (UWORD8)0x09, + (UWORD8)0x2B, (UWORD8)0x3B, (UWORD8)0x12, (UWORD8)0x3B, (UWORD8)0x2B, (UWORD8)0x3B, + (UWORD8)0x09, (UWORD8)0x13, (UWORD8)0x0A, (UWORD8)0x26, (UWORD8)0x16, (UWORD8)0x3D, + (UWORD8)0x12, (UWORD8)0x26, (UWORD8)0x18, (UWORD8)0x0C, (UWORD8)0x07, (UWORD8)0x39, + (UWORD8)0x1C, (UWORD8)0x0B, (UWORD8)0x39, (UWORD8)0x39, (UWORD8)0x0B, (UWORD8)0x12, + (UWORD8)0x0B, (UWORD8)0x26, (UWORD8)0x28, (UWORD8)0x10, (UWORD8)0x3D, (UWORD8)0x16, + (UWORD8)0x26, (UWORD8)0x18, (UWORD8)0x39, (UWORD8)0x39, (UWORD8)0x0B, (UWORD8)0x0B, + (UWORD8)0x1C, (UWORD8)0x25, (UWORD8)0x26, (UWORD8)0x1C, (UWORD8)0x18, (UWORD8)0x18, + (UWORD8)0x07, (UWORD8)0x0B, (UWORD8)0x0B, (UWORD8)0x3D, (UWORD8)0x25, (UWORD8)0x16, + (UWORD8)0x25, (UWORD8)0x18, (UWORD8)0x0B, (UWORD8)0x0B, (UWORD8)0x3D, (UWORD8)0x2B, + (UWORD8)0x16, (UWORD8)0x1F, (UWORD8)0x18, (UWORD8)0x0B, (UWORD8)0x26, (UWORD8)0x3D, + (UWORD8)0x1F, (UWORD8)0x3D, (UWORD8)0x12, (UWORD8)0x18, (UWORD8)0x39, (UWORD8)0x0E, + (UWORD8)0x3D, (UWORD8)0x2E, (UWORD8)0x16, (UWORD8)0x18, (UWORD8)0x0E, (UWORD8)0x0E, + (UWORD8)0x2E, (UWORD8)0x16, (UWORD8)0x18, (UWORD8)0x0E, (UWORD8)0x1C, (UWORD8)0x1C, + (UWORD8)0x18, (UWORD8)0x0E, (UWORD8)0x19, (UWORD8)0x1C, (UWORD8)0x2E, (UWORD8)0x2E, + (UWORD8)0x0C, (UWORD8)0x3D, (UWORD8)0x22, (UWORD8)0x18, (UWORD8)0x32, (UWORD8)0x3E, + (UWORD8)0x03, (UWORD8)0x1A, (UWORD8)0x1A, (UWORD8)0x30, (UWORD8)0x30, (UWORD8)0x1D, + (UWORD8)0x02, (UWORD8)0x02, (UWORD8)0x02, (UWORD8)0x08, (UWORD8)0x36, (UWORD8)0x36, + (UWORD8)0x35, (UWORD8)0x3B, (UWORD8)0x03, (UWORD8)0x1A, (UWORD8)0x30, (UWORD8)0x30, + (UWORD8)0x30, (UWORD8)0x02, (UWORD8)0x04, (UWORD8)0x04, (UWORD8)0x04, (UWORD8)0x39, + (UWORD8)0x20, (UWORD8)0x20, (UWORD8)0x09, (UWORD8)0x3B, (UWORD8)0x0A, (UWORD8)0x12, + (UWORD8)0x1A, (UWORD8)0x30, (UWORD8)0x2C, (UWORD8)0x2A, (UWORD8)0x2A, (UWORD8)0x2D, + (UWORD8)0x2D, (UWORD8)0x07, (UWORD8)0x34, (UWORD8)0x34, (UWORD8)0x39, (UWORD8)0x34, + (UWORD8)0x34, (UWORD8)0x34, (UWORD8)0x0B, (UWORD8)0x0B, (UWORD8)0x24, (UWORD8)0x02, + (UWORD8)0x04, (UWORD8)0x39, (UWORD8)0x39, (UWORD8)0x0A, (UWORD8)0x34, (UWORD8)0x07, + (UWORD8)0x34, (UWORD8)0x34, (UWORD8)0x0E, (UWORD8)0x34, (UWORD8)0x0E, (UWORD8)0x02, + (UWORD8)0x39, (UWORD8)0x39, (UWORD8)0x39, (UWORD8)0x07, (UWORD8)0x0E, (UWORD8)0x34, + (UWORD8)0x0E, (UWORD8)0x07, (UWORD8)0x39, (UWORD8)0x39, (UWORD8)0x39, (UWORD8)0x34, + (UWORD8)0x07, (UWORD8)0x39, (UWORD8)0x07, (UWORD8)0x0C, (UWORD8)0x07, (UWORD8)0x07, + (UWORD8)0x0C, (UWORD8)0x0C, (UWORD8)0x07, (UWORD8)0x39, (UWORD8)0x07, (UWORD8)0x39, + (UWORD8)0x0E, (UWORD8)0x01, (UWORD8)0x27, (UWORD8)0x27, (UWORD8)0x27, (UWORD8)0x2F, + (UWORD8)0x00, (UWORD8)0x00, (UWORD8)0x11, (UWORD8)0x27, (UWORD8)0x2F, (UWORD8)0x11, + (UWORD8)0x15, (UWORD8)0x00, (UWORD8)0x11, (UWORD8)0x15, (UWORD8)0x00, (UWORD8)0x00, + (UWORD8)0x01, (UWORD8)0x2F, (UWORD8)0x00, (UWORD8)0x15, (UWORD8)0x2F, (UWORD8)0x11, + (UWORD8)0x2F, (UWORD8)0x11, (UWORD8)0x11, (UWORD8)0x11, (UWORD8)0x11, (UWORD8)0x15, + (UWORD8)0x00, (UWORD8)0x11, (UWORD8)0x2F, (UWORD8)0x11, (UWORD8)0x2F, (UWORD8)0x11, + (UWORD8)0x01, (UWORD8)0x11, (UWORD8)0x2F, (UWORD8)0x11, (UWORD8)0x2F, (UWORD8)0x11, + (UWORD8)0x2F, (UWORD8)0x11, (UWORD8)0x11, (UWORD8)0x2F, (UWORD8)0x11, (UWORD8)0x2F, + (UWORD8)0x15, (UWORD8)0x17, (UWORD8)0x11, (UWORD8)0x27, (UWORD8)0x11, (UWORD8)0x11, + (UWORD8)0x11, (UWORD8)0x2F, (UWORD8)0x11, (UWORD8)0x2F, (UWORD8)0x11, (UWORD8)0x11, + (UWORD8)0x2F, (UWORD8)0x2F, (UWORD8)0x17, (UWORD8)0x15, (UWORD8)0x17, (UWORD8)0x27, + (UWORD8)0x27, (UWORD8)0x17, (UWORD8)0x2F, (UWORD8)0x27, (UWORD8)0x2F, (UWORD8)0x2F, + (UWORD8)0x27, (UWORD8)0x17, (UWORD8)0x2F, (UWORD8)0x27, (UWORD8)0x17, (UWORD8)0x2F, + (UWORD8)0x27, (UWORD8)0x2F, (UWORD8)0x2F, (UWORD8)0x27, (UWORD8)0x2F, (UWORD8)0x2F, + (UWORD8)0x27, (UWORD8)0x17, (UWORD8)0x2F, (UWORD8)0x27, (UWORD8)0x17, (UWORD8)0x2F, + (UWORD8)0x27, (UWORD8)0x17, (UWORD8)0x2F, (UWORD8)0x27, (UWORD8)0x27, (UWORD8)0x2B, + (UWORD8)0x17, (UWORD8)0x27, (UWORD8)0x2F, (UWORD8)0x27, (UWORD8)0x17, (UWORD8)0x2B, + (UWORD8)0x2F, (UWORD8)0x2F, (UWORD8)0x27, (UWORD8)0x01, (UWORD8)0x00, (UWORD8)0x15, + (UWORD8)0x00, (UWORD8)0x11, (UWORD8)0x00, (UWORD8)0x27, (UWORD8)0x00, (UWORD8)0x15, + (UWORD8)0x17, (UWORD8)0x17, (UWORD8)0x15, (UWORD8)0x17, (UWORD8)0x27, (UWORD8)0x17, + (UWORD8)0x17, (UWORD8)0x17, (UWORD8)0x17, (UWORD8)0x27, (UWORD8)0x27, (UWORD8)0x27, + (UWORD8)0x15, (UWORD8)0x2F, (UWORD8)0x27, (UWORD8)0x2F, (UWORD8)0x27, (UWORD8)0x2F, + (UWORD8)0x15, (UWORD8)0x2F, (UWORD8)0x27, (UWORD8)0x2F, (UWORD8)0x27, (UWORD8)0x17, + (UWORD8)0x27, (UWORD8)0x17, (UWORD8)0x27, (UWORD8)0x2F, (UWORD8)0x27, (UWORD8)0x17, + (UWORD8)0x17, (UWORD8)0x17, (UWORD8)0x15, (UWORD8)0x00}; + +const UWORD16 iusace_ari_cf_m[64][17] = { + {708, 706, 579, 569, 568, 567, 479, 469, 297, 138, 97, 91, 72, 52, 38, 34, 0}, + {7619, 6917, 6519, 6412, 5514, 5003, 4683, 4563, 3907, 3297, 3125, 3060, 2904, 2718, 2631, + 2590, 0}, + {7263, 4888, 4810, 4803, 1889, 415, 335, 327, 195, 72, 52, 49, 36, 20, 15, 14, 0}, + {3626, 2197, 2188, 2187, 582, 57, 47, 46, 30, 12, 9, 8, 6, 4, 3, 2, 0}, + {7806, 5541, 5451, 5441, 2720, 834, 691, 674, 487, 243, 179, 167, 139, 98, 77, 70, 0}, + {6684, 4101, 4058, 4055, 1748, 426, 368, 364, 322, 257, 235, 232, 228, 222, 217, 215, 0}, + {9162, 5964, 5831, 5819, 3269, 866, 658, 638, 535, 348, 258, 244, 234, 214, 195, 186, 0}, + {10638, 8491, 8365, 8351, 4418, 2067, 1859, 1834, 1190, 601, 495, 478, 356, 217, 174, 164, 0}, + {13389, 10514, 10032, 9961, 7166, 3488, 2655, 2524, 2015, 1140, 760, 672, 585, 426, 325, 283, + 0}, + {14861, 12788, 12115, 11952, 9987, 6657, 5323, 4984, 4324, 3001, 2205, 1943, 1764, 1394, 1115, + 978, 0}, + {12876, 10004, 9661, 9610, 7107, 3435, 2711, 2595, 2257, 1508, 1059, 952, 893, 753, 609, 538, + 0}, + {15125, 13591, 13049, 12874, 11192, 8543, 7406, 7023, 6291, 4922, 4104, 3769, 3465, 2890, + 2486, 2275, 0}, + {14574, 13106, 12731, 12638, 10453, 7947, 7233, 7037, 6031, 4618, 4081, 3906, 3465, 2802, + 2476, 2349, 0}, + {15070, 13179, 12517, 12351, 10742, 7657, 6200, 5825, 5264, 3998, 3014, 2662, 2510, 2153, + 1799, 1564, 0}, + {15542, 14466, 14007, 13844, 12489, 10409, 9481, 9132, 8305, 6940, 6193, 5867, 5458, 4743, + 4291, 4047, 0}, + {15165, 14384, 14084, 13934, 12911, 11485, 10844, 10513, 10002, 8993, 8380, 8051, 7711, 7036, + 6514, 6233, 0}, + {15642, 14279, 13625, 13393, 12348, 9971, 8405, 7858, 7335, 6119, 4918, 4376, 4185, 3719, + 3231, 2860, 0}, + {13408, 13407, 11471, 11218, 11217, 11216, 9473, 9216, 6480, 3689, 2857, 2690, 2256, 1732, + 1405, 1302, 0}, + {16098, 15584, 15191, 14931, 14514, 13578, 12703, 12103, 11830, 11172, 10475, 9867, 9695, + 9281, 8825, 8389, 0}, + {15844, 14873, 14277, 13996, 13230, 11535, 10205, 9543, 9107, 8086, 7085, 6419, 6214, 5713, + 5195, 4731, 0}, + {16131, 15720, 15443, 15276, 14848, 13971, 13314, 12910, 12591, 11874, 11225, 10788, 10573, + 10077, 9585, 9209, 0}, + {16331, 16330, 12283, 11435, 11434, 11433, 8725, 8049, 6065, 4138, 3187, 2842, 2529, 2171, + 1907, 1745, 0}, + {16011, 15292, 14782, 14528, 14008, 12767, 11556, 10921, 10591, 9759, 8813, 8043, 7855, 7383, + 6863, 6282, 0}, + {16380, 16379, 15159, 14610, 14609, 14608, 12859, 12111, 11046, 9536, 8348, 7713, 7216, 6533, + 5964, 5546, 0}, + {16367, 16333, 16294, 16253, 16222, 16143, 16048, 15947, 15915, 15832, 15731, 15619, 15589, + 15512, 15416, 15310, 0}, + {15967, 15319, 14937, 14753, 14010, 12638, 11787, 11360, 10805, 9706, 8934, 8515, 8166, 7456, + 6911, 6575, 0}, + {4906, 3005, 2985, 2984, 875, 102, 83, 81, 47, 17, 12, 11, 8, 5, 4, 3, 0}, + {7217, 4346, 4269, 4264, 1924, 428, 340, 332, 280, 203, 179, 175, 171, 164, 159, 157, 0}, + {16010, 15415, 15032, 14805, 14228, 13043, 12168, 11634, 11265, 10419, 9645, 9110, 8892, 8378, + 7850, 7437, 0}, + {8573, 5218, 5046, 5032, 2787, 771, 555, 533, 443, 286, 218, 205, 197, 181, 168, 162, 0}, + {11474, 8095, 7822, 7796, 4632, 1443, 1046, 1004, 748, 351, 218, 194, 167, 121, 93, 83, 0}, + {16152, 15764, 15463, 15264, 14925, 14189, 13536, 13070, 12846, 12314, 11763, 11277, 11131, + 10777, 10383, 10011, 0}, + {14187, 11654, 11043, 10919, 8498, 4885, 3778, 3552, 2947, 1835, 1283, 1134, 998, 749, 585, + 514, 0}, + {14162, 11527, 10759, 10557, 8601, 5417, 4105, 3753, 3286, 2353, 1708, 1473, 1370, 1148, 959, + 840, 0}, + {16205, 15902, 15669, 15498, 15213, 14601, 14068, 13674, 13463, 12970, 12471, 12061, 11916, + 11564, 11183, 10841, 0}, + {15043, 12972, 12092, 11792, 10265, 7446, 5934, 5379, 4883, 3825, 3036, 2647, 2507, 2185, + 1901, 1699, 0}, + {15320, 13694, 12782, 12352, 11191, 8936, 7433, 6671, 6255, 5366, 4622, 4158, 4020, 3712, + 3420, 3198, 0}, + {16255, 16020, 15768, 15600, 15416, 14963, 14440, 14006, 13875, 13534, 13137, 12697, 12602, + 12364, 12084, 11781, 0}, + {15627, 14503, 13906, 13622, 12557, 10527, 9269, 8661, 8117, 6933, 5994, 5474, 5222, 4664, + 4166, 3841, 0}, + {16366, 16365, 14547, 14160, 14159, 14158, 11969, 11473, 8735, 6147, 4911, 4530, 3865, 3180, + 2710, 2473, 0}, + {16257, 16038, 15871, 15754, 15536, 15071, 14673, 14390, 14230, 13842, 13452, 13136, 13021, + 12745, 12434, 12154, 0}, + {15855, 14971, 14338, 13939, 13239, 11782, 10585, 9805, 9444, 8623, 7846, 7254, 7079, 6673, + 6262, 5923, 0}, + {9492, 6318, 6197, 6189, 3004, 652, 489, 477, 333, 143, 96, 90, 78, 60, 50, 47, 0}, + {16313, 16191, 16063, 15968, 15851, 15590, 15303, 15082, 14968, 14704, 14427, 14177, 14095, + 13899, 13674, 13457, 0}, + {8485, 5473, 5389, 5383, 2411, 494, 386, 377, 278, 150, 117, 112, 103, 89, 81, 78, 0}, + {10497, 7154, 6959, 6943, 3788, 1004, 734, 709, 517, 238, 152, 138, 120, 90, 72, 66, 0}, + {16317, 16226, 16127, 16040, 15955, 15762, 15547, 15345, 15277, 15111, 14922, 14723, 14671, + 14546, 14396, 14239, 0}, + {16382, 16381, 15858, 15540, 15539, 15538, 14704, 14168, 13768, 13092, 12452, 11925, 11683, + 11268, 10841, 10460, 0}, + {5974, 3798, 3758, 3755, 1275, 205, 166, 162, 95, 35, 26, 24, 18, 11, 8, 7, 0}, + {3532, 2258, 2246, 2244, 731, 135, 118, 115, 87, 45, 36, 34, 29, 21, 17, 16, 0}, + {7466, 4882, 4821, 4811, 2476, 886, 788, 771, 688, 531, 469, 457, 437, 400, 369, 361, 0}, + {9580, 5772, 5291, 5216, 3444, 1496, 1025, 928, 806, 578, 433, 384, 366, 331, 296, 273, 0}, + {10692, 7730, 7543, 7521, 4679, 1746, 1391, 1346, 1128, 692, 495, 458, 424, 353, 291, 268, 0}, + {11040, 7132, 6549, 6452, 4377, 1875, 1253, 1130, 958, 631, 431, 370, 346, 296, 253, 227, 0}, + {12687, 9332, 8701, 8585, 6266, 3093, 2182, 2004, 1683, 1072, 712, 608, 559, 458, 373, 323, + 0}, + {13429, 9853, 8860, 8584, 6806, 4039, 2862, 2478, 2239, 1764, 1409, 1224, 1178, 1077, 979, + 903, 0}, + {14685, 12163, 11061, 10668, 9101, 6345, 4871, 4263, 3908, 3200, 2668, 2368, 2285, 2106, 1942, + 1819, 0}, + {13295, 11302, 10999, 10945, 7947, 5036, 4490, 4385, 3391, 2185, 1836, 1757, 1424, 998, 833, + 785, 0}, + {4992, 2993, 2972, 2970, 1269, 575, 552, 549, 530, 505, 497, 495, 493, 489, 486, 485, 0}, + {15419, 13862, 13104, 12819, 11429, 8753, 7220, 6651, 6020, 4667, 3663, 3220, 2995, 2511, + 2107, 1871, 0}, + {12468, 9263, 8912, 8873, 5758, 2193, 1625, 1556, 1187, 589, 371, 330, 283, 200, 149, 131, 0}, + {15870, 15076, 14615, 14369, 13586, 12034, 10990, 10423, 9953, 8908, 8031, 7488, 7233, 6648, + 6101, 5712, 0}, + {1693, 978, 976, 975, 194, 18, 16, 15, 11, 7, 6, 5, 4, 3, 2, 1, 0}, + {7992, 5218, 5147, 5143, 2152, 366, 282, 276, 173, 59, 38, 35, 27, 16, 11, 10, 0}}; + +const FLOAT32 iusace_pre_post_twid_cos_sin_512[4][512] = { + + {0.999999702f, 0.999992669f, 0.999976158f, 0.999950290f, 0.999915004f, 0.999870300f, + 0.999816179f, 0.999752641f, 0.999679685f, 0.999597371f, 0.999505579f, 0.999404430f, + 0.999293864f, 0.999173880f, 0.999044478f, 0.998905718f, 0.998757541f, 0.998599946f, + 0.998432934f, 0.998256564f, 0.998070776f, 0.997875631f, 0.997671068f, 0.997457087f, + 0.997233748f, 0.997000992f, 0.996758878f, 0.996507406f, 0.996246517f, 0.995976269f, + 0.995696604f, 0.995407641f, 0.995109260f, 0.994801521f, 0.994484425f, 0.994157970f, + 0.993822157f, 0.993476987f, 0.993122458f, 0.992758572f, 0.992385328f, 0.992002785f, + 0.991610885f, 0.991209686f, 0.990799129f, 0.990379214f, 0.989950061f, 0.989511490f, + 0.989063680f, 0.988606513f, 0.988140106f, 0.987664342f, 0.987179279f, 0.986684918f, + 0.986181319f, 0.985668421f, 0.985146224f, 0.984614789f, 0.984074056f, 0.983524024f, + 0.982964814f, 0.982396305f, 0.981818557f, 0.981231570f, 0.980635345f, 0.980029881f, + 0.979415238f, 0.978791356f, 0.978158236f, 0.977515936f, 0.976864398f, 0.976203680f, + 0.975533783f, 0.974854708f, 0.974166453f, 0.973469019f, 0.972762465f, 0.972046733f, + 0.971321821f, 0.970587790f, 0.969844580f, 0.969092309f, 0.968330860f, 0.967560351f, + 0.966780722f, 0.965991974f, 0.965194106f, 0.964387238f, 0.963571191f, 0.962746143f, + 0.961912036f, 0.961068869f, 0.960216641f, 0.959355354f, 0.958485067f, 0.957605720f, + 0.956717432f, 0.955820084f, 0.954913735f, 0.953998446f, 0.953074098f, 0.952140868f, + 0.951198637f, 0.950247467f, 0.949287295f, 0.948318243f, 0.947340250f, 0.946353376f, + 0.945357561f, 0.944352806f, 0.943339229f, 0.942316771f, 0.941285372f, 0.940245211f, + 0.939196110f, 0.938138247f, 0.937071502f, 0.935995936f, 0.934911609f, 0.933818460f, + 0.932716489f, 0.931605756f, 0.930486262f, 0.929358006f, 0.928220987f, 0.927075267f, + 0.925920784f, 0.924757600f, 0.923585773f, 0.922405183f, 0.921215892f, 0.920017958f, + 0.918811381f, 0.917596161f, 0.916372299f, 0.915139794f, 0.913898647f, 0.912648976f, + 0.911390662f, 0.910123765f, 0.908848345f, 0.907564342f, 0.906271756f, 0.904970706f, + 0.903661072f, 0.902342975f, 0.901016414f, 0.899681330f, 0.898337781f, 0.896985769f, + 0.895625353f, 0.894256473f, 0.892879188f, 0.891493499f, 0.890099406f, 0.888696969f, + 0.887286127f, 0.885866940f, 0.884439468f, 0.883003592f, 0.881559432f, 0.880106986f, + 0.878646255f, 0.877177238f, 0.875699997f, 0.874214530f, 0.872720778f, 0.871218860f, + 0.869708657f, 0.868190348f, 0.866663873f, 0.865129173f, 0.863586366f, 0.862035453f, + 0.860476434f, 0.858909249f, 0.857334018f, 0.855750740f, 0.854159415f, 0.852559984f, + 0.850952566f, 0.849337161f, 0.847713768f, 0.846082330f, 0.844442964f, 0.842795670f, + 0.841140449f, 0.839477241f, 0.837806225f, 0.836127281f, 0.834440410f, 0.832745790f, + 0.831043243f, 0.829332948f, 0.827614784f, 0.825888872f, 0.824155152f, 0.822413683f, + 0.820664465f, 0.818907559f, 0.817142904f, 0.815370619f, 0.813590586f, 0.811802983f, + 0.810007632f, 0.808204710f, 0.806394219f, 0.804576099f, 0.802750409f, 0.800917149f, + 0.799076378f, 0.797228038f, 0.795372248f, 0.793508947f, 0.791638196f, 0.789759994f, + 0.787874341f, 0.785981238f, 0.784080803f, 0.782172918f, 0.780257761f, 0.778335214f, + 0.776405334f, 0.774468124f, 0.772523642f, 0.770571887f, 0.768612921f, 0.766646683f, + 0.764673233f, 0.762692571f, 0.760704756f, 0.758709788f, 0.756707668f, 0.754698396f, + 0.752682030f, 0.750658631f, 0.748628080f, 0.746590555f, 0.744545996f, 0.742494404f, + 0.740435839f, 0.738370299f, 0.736297786f, 0.734218359f, 0.732132018f, 0.730038822f, + 0.727938712f, 0.725831807f, 0.723717988f, 0.721597433f, 0.719470024f, 0.717335880f, + 0.715194941f, 0.713047326f, 0.710892975f, 0.708731949f, 0.706564248f, 0.704389870f, + 0.702208877f, 0.700021267f, 0.697827101f, 0.695626318f, 0.693419039f, 0.691205204f, + 0.688984871f, 0.686758041f, 0.684524715f, 0.682285011f, 0.680038869f, 0.677786291f, + 0.675527394f, 0.673262060f, 0.670990467f, 0.668712497f, 0.666428268f, 0.664137781f, + 0.661840975f, 0.659538031f, 0.657228827f, 0.654913425f, 0.652591884f, 0.650264204f, + 0.647930384f, 0.645590484f, 0.643244505f, 0.640892446f, 0.638534367f, 0.636170268f, + 0.633800209f, 0.631424189f, 0.629042208f, 0.626654267f, 0.624260485f, 0.621860802f, + 0.619455278f, 0.617043912f, 0.614626765f, 0.612203777f, 0.609775066f, 0.607340634f, + 0.604900479f, 0.602454603f, 0.600003064f, 0.597545862f, 0.595083058f, 0.592614651f, + 0.590140700f, 0.587661147f, 0.585176051f, 0.582685471f, 0.580189407f, 0.577687919f, + 0.575180948f, 0.572668552f, 0.570150793f, 0.567627668f, 0.565099180f, 0.562565386f, + 0.560026288f, 0.557481945f, 0.554932356f, 0.552377522f, 0.549817502f, 0.547252297f, + 0.544681907f, 0.542106450f, 0.539525867f, 0.536940157f, 0.534349442f, 0.531753719f, + 0.529152989f, 0.526547253f, 0.523936570f, 0.521320939f, 0.518700421f, 0.516075015f, + 0.513444722f, 0.510809600f, 0.508169711f, 0.505525053f, 0.502875566f, 0.500221372f, + 0.497562498f, 0.494898945f, 0.492230713f, 0.489557832f, 0.486880362f, 0.484198302f, + 0.481511682f, 0.478820562f, 0.476124883f, 0.473424762f, 0.470720172f, 0.468011141f, + 0.465297729f, 0.462579936f, 0.459857762f, 0.457131267f, 0.454400480f, 0.451665431f, + 0.448926091f, 0.446182549f, 0.443434805f, 0.440682888f, 0.437926829f, 0.435166657f, + 0.432402372f, 0.429634005f, 0.426861614f, 0.424085200f, 0.421304792f, 0.418520421f, + 0.415732116f, 0.412939876f, 0.410143793f, 0.407343805f, 0.404540002f, 0.401732385f, + 0.398921013f, 0.396105856f, 0.393286973f, 0.390464395f, 0.387638152f, 0.384808242f, + 0.381974727f, 0.379137605f, 0.376296908f, 0.373452663f, 0.370604932f, 0.367753685f, + 0.364899009f, 0.362040877f, 0.359179348f, 0.356314421f, 0.353446156f, 0.350574553f, + 0.347699642f, 0.344821483f, 0.341940075f, 0.339055419f, 0.336167604f, 0.333276600f, + 0.330382496f, 0.327485234f, 0.324584931f, 0.321681559f, 0.318775147f, 0.315865755f, + 0.312953383f, 0.310038060f, 0.307119817f, 0.304198682f, 0.301274687f, 0.298347861f, + 0.295418203f, 0.292485803f, 0.289550632f, 0.286612719f, 0.283672124f, 0.280728877f, + 0.277782977f, 0.274834454f, 0.271883339f, 0.268929660f, 0.265973479f, 0.263014764f, + 0.260053605f, 0.257089972f, 0.254123926f, 0.251155496f, 0.248184681f, 0.245211542f, + 0.242236108f, 0.239258379f, 0.236278400f, 0.233296201f, 0.230311811f, 0.227325246f, + 0.224336535f, 0.221345723f, 0.218352824f, 0.215357870f, 0.212360889f, 0.209361911f, + 0.206360951f, 0.203358069f, 0.200353250f, 0.197346568f, 0.194338009f, 0.191327631f, + 0.188315451f, 0.185301498f, 0.182285801f, 0.179268390f, 0.176249295f, 0.173228532f, + 0.170206144f, 0.167182148f, 0.164156586f, 0.161129475f, 0.158100843f, 0.155070737f, + 0.152039155f, 0.149006143f, 0.145971745f, 0.142935961f, 0.139898837f, 0.136860386f, + 0.133820653f, 0.130779669f, 0.127737448f, 0.124694020f, 0.121649414f, 0.118603677f, + 0.115556814f, 0.112508863f, 0.109459855f, 0.106409818f, 0.103358783f, 0.100306772f, + 0.097253814f, 0.094199941f, 0.091145188f, 0.088089570f, 0.085033126f, 0.081975877f, + 0.078917861f, 0.075859107f, 0.072799630f, 0.069739468f, 0.066678658f, 0.063617215f, + 0.060555171f, 0.057492558f, 0.054429408f, 0.051365741f, 0.048301592f, 0.045236990f, + 0.042171963f, 0.039106537f, 0.036040742f, 0.032974608f, 0.029908165f, 0.026841439f, + 0.023774462f, 0.020707261f, 0.017639864f, 0.014572302f, 0.011504602f, 0.008436794f, + 0.005368907f, 0.002300969f}, + {-0.000766990f, -0.003834943f, -0.006902859f, -0.009970710f, -0.013038468f, -0.016106103f, + -0.019173585f, -0.022240888f, -0.025307981f, -0.028374836f, -0.031441424f, -0.034507714f, + -0.037573684f, -0.040639296f, -0.043704528f, -0.046769347f, -0.049833726f, -0.052897636f, + -0.055961050f, -0.059023935f, -0.062086266f, -0.065148011f, -0.068209141f, -0.071269631f, + -0.074329451f, -0.077388577f, -0.080446966f, -0.083504602f, -0.086561449f, -0.089617483f, + -0.092672676f, -0.095726989f, -0.098780409f, -0.101832896f, -0.104884423f, -0.107934967f, + -0.110984489f, -0.114032976f, -0.117080383f, -0.120126687f, -0.123171858f, -0.126215875f, + -0.129258707f, -0.132300317f, -0.135340676f, -0.138379768f, -0.141417563f, -0.144454017f, + -0.147489116f, -0.150522828f, -0.153555125f, -0.156585976f, -0.159615353f, -0.162643224f, + -0.165669560f, -0.168694347f, -0.171717539f, -0.174739107f, -0.177759051f, -0.180777311f, + -0.183793873f, -0.186808690f, -0.189821765f, -0.192833051f, -0.195842519f, -0.198850140f, + -0.201855898f, -0.204859748f, -0.207861677f, -0.210861638f, -0.213859633f, -0.216855600f, + -0.219849527f, -0.222841397f, -0.225831151f, -0.228818789f, -0.231804281f, -0.234787583f, + -0.237768665f, -0.240747526f, -0.243724108f, -0.246698409f, -0.249670386f, -0.252640009f, + -0.255607247f, -0.258572072f, -0.261534482f, -0.264494419f, -0.267451882f, -0.270406812f, + -0.273359209f, -0.276309043f, -0.279256254f, -0.282200843f, -0.285142779f, -0.288082033f, + -0.291018546f, -0.293952346f, -0.296883374f, -0.299811631f, -0.302737027f, -0.305659592f, + -0.308579296f, -0.311496079f, -0.314409941f, -0.317320824f, -0.320228726f, -0.323133618f, + -0.326035470f, -0.328934252f, -0.331829935f, -0.334722489f, -0.337611914f, -0.340498149f, + -0.343381166f, -0.346260965f, -0.349137515f, -0.352010757f, -0.354880691f, -0.357747287f, + -0.360610515f, -0.363470376f, -0.366326779f, -0.369179755f, -0.372029245f, -0.374875218f, + -0.377717704f, -0.380556613f, -0.383391917f, -0.386223644f, -0.389051735f, -0.391876131f, + -0.394696862f, -0.397513896f, -0.400327176f, -0.403136671f, -0.405942380f, -0.408744276f, + -0.411542326f, -0.414336503f, -0.417126775f, -0.419913113f, -0.422695488f, -0.425473899f, + -0.428248316f, -0.431018710f, -0.433785021f, -0.436547250f, -0.439305395f, -0.442059368f, + -0.444809198f, -0.447554857f, -0.450296283f, -0.453033477f, -0.455766410f, -0.458495051f, + -0.461219400f, -0.463939369f, -0.466654986f, -0.469366223f, -0.472073019f, -0.474775374f, + -0.477473289f, -0.480166674f, -0.482855558f, -0.485539913f, -0.488219678f, -0.490894854f, + -0.493565410f, -0.496231288f, -0.498892546f, -0.501549065f, -0.504200876f, -0.506847978f, + -0.509490252f, -0.512127757f, -0.514760435f, -0.517388284f, -0.520011246f, -0.522629380f, + -0.525242507f, -0.527850747f, -0.530453980f, -0.533052206f, -0.535645485f, -0.538233638f, + -0.540816784f, -0.543394804f, -0.545967758f, -0.548535526f, -0.551098168f, -0.553655565f, + -0.556207776f, -0.558754802f, -0.561296523f, -0.563832939f, -0.566364110f, -0.568889916f, + -0.571410358f, -0.573925436f, -0.576435089f, -0.578939319f, -0.581438124f, -0.583931446f, + -0.586419284f, -0.588901579f, -0.591378391f, -0.593849599f, -0.596315205f, -0.598775208f, + -0.601229548f, -0.603678226f, -0.606121242f, -0.608558595f, -0.610990167f, -0.613416016f, + -0.615836084f, -0.618250310f, -0.620658755f, -0.623061359f, -0.625458121f, -0.627848983f, + -0.630233943f, -0.632612944f, -0.634985983f, -0.637353063f, -0.639714181f, -0.642069221f, + -0.644418240f, -0.646761179f, -0.649098039f, -0.651428819f, -0.653753400f, -0.656071901f, + -0.658384204f, -0.660690308f, -0.662990153f, -0.665283799f, -0.667571187f, -0.669852257f, + -0.672127068f, -0.674395502f, -0.676657617f, -0.678913355f, -0.681162715f, -0.683405697f, + -0.685642183f, -0.687872231f, -0.690095842f, -0.692312896f, -0.694523513f, -0.696727514f, + -0.698925018f, -0.701115906f, -0.703300178f, -0.705477893f, -0.707648933f, -0.709813297f, + -0.711970985f, -0.714121997f, -0.716266274f, -0.718403816f, -0.720534563f, -0.722658575f, + -0.724775732f, -0.726886094f, -0.728989601f, -0.731086314f, -0.733176053f, -0.735258937f, + -0.737334907f, -0.739403903f, -0.741465986f, -0.743521094f, -0.745569170f, -0.747610211f, + -0.749644220f, -0.751671195f, -0.753691137f, -0.755703926f, -0.757709622f, -0.759708166f, + -0.761699557f, -0.763683796f, -0.765660882f, -0.767630696f, -0.769593298f, -0.771548688f, + -0.773496807f, -0.775437653f, -0.777371168f, -0.779297352f, -0.781216264f, -0.783127785f, + -0.785031915f, -0.786928713f, -0.788818061f, -0.790700018f, -0.792574525f, -0.794441521f, + -0.796301067f, -0.798153162f, -0.799997687f, -0.801834702f, -0.803664207f, -0.805486083f, + -0.807300448f, -0.809107125f, -0.810906231f, -0.812697768f, -0.814481556f, -0.816257715f, + -0.818026185f, -0.819786966f, -0.821540058f, -0.823285401f, -0.825022995f, -0.826752782f, + -0.828474820f, -0.830189049f, -0.831895471f, -0.833594084f, -0.835284829f, -0.836967707f, + -0.838642716f, -0.840309858f, -0.841969013f, -0.843620300f, -0.845263660f, -0.846899033f, + -0.848526478f, -0.850145876f, -0.851757288f, -0.853360713f, -0.854956090f, -0.856543422f, + -0.858122647f, -0.859693885f, -0.861256957f, -0.862811923f, -0.864358783f, -0.865897536f, + -0.867428124f, -0.868950546f, -0.870464802f, -0.871970832f, -0.873468697f, -0.874958277f, + -0.876439691f, -0.877912819f, -0.879377663f, -0.880834281f, -0.882282555f, -0.883722544f, + -0.885154247f, -0.886577606f, -0.887992561f, -0.889399230f, -0.890797496f, -0.892187417f, + -0.893568873f, -0.894941986f, -0.896306634f, -0.897662818f, -0.899010599f, -0.900349915f, + -0.901680768f, -0.903003097f, -0.904316962f, -0.905622303f, -0.906919122f, -0.908207357f, + -0.909487128f, -0.910758257f, -0.912020862f, -0.913274884f, -0.914520323f, -0.915757120f, + -0.916985273f, -0.918204844f, -0.919415772f, -0.920618057f, -0.921811640f, -0.922996521f, + -0.924172759f, -0.925340295f, -0.926499128f, -0.927649260f, -0.928790629f, -0.929923236f, + -0.931047082f, -0.932162225f, -0.933268547f, -0.934366107f, -0.935454845f, -0.936534822f, + -0.937605977f, -0.938668311f, -0.939721763f, -0.940766394f, -0.941802204f, -0.942829072f, + -0.943847120f, -0.944856286f, -0.945856571f, -0.946847916f, -0.947830379f, -0.948803902f, + -0.949768484f, -0.950724125f, -0.951670885f, -0.952608585f, -0.953537405f, -0.954457223f, + -0.955368042f, -0.956269860f, -0.957162678f, -0.958046496f, -0.958921313f, -0.959787130f, + -0.960643888f, -0.961491585f, -0.962330222f, -0.963159800f, -0.963980377f, -0.964791834f, + -0.965594172f, -0.966387451f, -0.967171669f, -0.967946768f, -0.968712747f, -0.969469607f, + -0.970217347f, -0.970955908f, -0.971685410f, -0.972405732f, -0.973116875f, -0.973818898f, + -0.974511743f, -0.975195408f, -0.975869894f, -0.976535201f, -0.977191329f, -0.977838218f, + -0.978475928f, -0.979104459f, -0.979723752f, -0.980333805f, -0.980934620f, -0.981526256f, + -0.982108593f, -0.982681692f, -0.983245611f, -0.983800232f, -0.984345555f, -0.984881639f, + -0.985408485f, -0.985926032f, -0.986434281f, -0.986933291f, -0.987422943f, -0.987903357f, + -0.988374472f, -0.988836288f, -0.989288747f, -0.989731967f, -0.990165830f, -0.990590334f, + -0.991005540f, -0.991411448f, -0.991807997f, -0.992195249f, -0.992573142f, -0.992941678f, + -0.993300855f, -0.993650734f, -0.993991196f, -0.994322360f, -0.994644165f, -0.994956553f, + -0.995259583f, -0.995553315f, -0.995837629f, -0.996112585f, -0.996378124f, -0.996634305f, + -0.996881127f, -0.997118533f, -0.997346580f, -0.997565210f, -0.997774482f, -0.997974396f, + -0.998164833f, -0.998345912f, -0.998517632f, -0.998679936f, -0.998832822f, -0.998976290f, + -0.999110341f, -0.999235034f, -0.999350309f, -0.999456167f, -0.999552667f, -0.999639690f, + -0.999717355f, -0.999785602f, -0.999844432f, -0.999893844f, -0.999933839f, -0.999964416f, + -0.999985576f, -0.999997377f}, + {1.000000000f, 0.999995291f, 0.999981165f, 0.999957621f, 0.999924719f, 0.999882340f, + 0.999830604f, 0.999769390f, 0.999698818f, 0.999618828f, 0.999529421f, 0.999430597f, + 0.999322355f, 0.999204755f, 0.999077737f, 0.998941302f, 0.998795450f, 0.998640239f, + 0.998475552f, 0.998301566f, 0.998118103f, 0.997925282f, 0.997723043f, 0.997511446f, + 0.997290432f, 0.997060061f, 0.996820271f, 0.996571124f, 0.996312618f, 0.996044695f, + 0.995767415f, 0.995480776f, 0.995184720f, 0.994879305f, 0.994564593f, 0.994240463f, + 0.993906975f, 0.993564129f, 0.993211925f, 0.992850423f, 0.992479563f, 0.992099285f, + 0.991709769f, 0.991310835f, 0.990902662f, 0.990485072f, 0.990058184f, 0.989621997f, + 0.989176512f, 0.988721669f, 0.988257587f, 0.987784147f, 0.987301409f, 0.986809373f, + 0.986308098f, 0.985797524f, 0.985277653f, 0.984748483f, 0.984210074f, 0.983662426f, + 0.983105481f, 0.982539296f, 0.981963873f, 0.981379211f, 0.980785251f, 0.980182111f, + 0.979569793f, 0.978948176f, 0.978317380f, 0.977677345f, 0.977028131f, 0.976369739f, + 0.975702107f, 0.975025356f, 0.974339366f, 0.973644257f, 0.972939968f, 0.972226501f, + 0.971503913f, 0.970772147f, 0.970031261f, 0.969281256f, 0.968522072f, 0.967753828f, + 0.966976464f, 0.966189981f, 0.965394437f, 0.964589775f, 0.963776052f, 0.962953269f, + 0.962121427f, 0.961280465f, 0.960430503f, 0.959571540f, 0.958703458f, 0.957826436f, + 0.956940353f, 0.956045270f, 0.955141187f, 0.954228103f, 0.953306019f, 0.952374995f, + 0.951435030f, 0.950486064f, 0.949528158f, 0.948561370f, 0.947585583f, 0.946600914f, + 0.945607305f, 0.944604814f, 0.943593442f, 0.942573190f, 0.941544056f, 0.940506041f, + 0.939459205f, 0.938403547f, 0.937339008f, 0.936265647f, 0.935183525f, 0.934092522f, + 0.932992816f, 0.931884289f, 0.930766940f, 0.929640889f, 0.928506076f, 0.927362502f, + 0.926210225f, 0.925049245f, 0.923879504f, 0.922701120f, 0.921514034f, 0.920318305f, + 0.919113874f, 0.917900801f, 0.916679084f, 0.915448725f, 0.914209783f, 0.912962198f, + 0.911706030f, 0.910441279f, 0.909168005f, 0.907886088f, 0.906595707f, 0.905296743f, + 0.903989315f, 0.902673304f, 0.901348829f, 0.900015891f, 0.898674488f, 0.897324562f, + 0.895966232f, 0.894599497f, 0.893224299f, 0.891840696f, 0.890448749f, 0.889048338f, + 0.887639642f, 0.886222541f, 0.884797096f, 0.883363366f, 0.881921291f, 0.880470872f, + 0.879012227f, 0.877545297f, 0.876070082f, 0.874586642f, 0.873094976f, 0.871595085f, + 0.870086968f, 0.868570685f, 0.867046237f, 0.865513623f, 0.863972843f, 0.862423956f, + 0.860866964f, 0.859301805f, 0.857728601f, 0.856147349f, 0.854557991f, 0.852960587f, + 0.851355195f, 0.849741757f, 0.848120332f, 0.846490920f, 0.844853580f, 0.843208253f, + 0.841554999f, 0.839893818f, 0.838224709f, 0.836547732f, 0.834862888f, 0.833170176f, + 0.831469595f, 0.829761207f, 0.828045070f, 0.826321065f, 0.824589312f, 0.822849810f, + 0.821102500f, 0.819347501f, 0.817584813f, 0.815814435f, 0.814036310f, 0.812250614f, + 0.810457170f, 0.808656156f, 0.806847572f, 0.805031359f, 0.803207517f, 0.801376164f, + 0.799537241f, 0.797690868f, 0.795836926f, 0.793975472f, 0.792106569f, 0.790230215f, + 0.788346410f, 0.786455214f, 0.784556568f, 0.782650590f, 0.780737221f, 0.778816521f, + 0.776888490f, 0.774953127f, 0.773010433f, 0.771060526f, 0.769103348f, 0.767138898f, + 0.765167236f, 0.763188422f, 0.761202395f, 0.759209216f, 0.757208824f, 0.755201399f, + 0.753186822f, 0.751165152f, 0.749136388f, 0.747100592f, 0.745057762f, 0.743007958f, + 0.740951121f, 0.738887310f, 0.736816585f, 0.734738886f, 0.732654274f, 0.730562747f, + 0.728464365f, 0.726359129f, 0.724247098f, 0.722128212f, 0.720002532f, 0.717870057f, + 0.715730846f, 0.713584840f, 0.711432219f, 0.709272802f, 0.707106769f, 0.704934061f, + 0.702754736f, 0.700568795f, 0.698376238f, 0.696177125f, 0.693971455f, 0.691759229f, + 0.689540565f, 0.687315345f, 0.685083687f, 0.682845533f, 0.680601001f, 0.678350031f, + 0.676092684f, 0.673829019f, 0.671558976f, 0.669282615f, 0.666999936f, 0.664710999f, + 0.662415802f, 0.660114348f, 0.657806695f, 0.655492842f, 0.653172851f, 0.650846660f, + 0.648514390f, 0.646176040f, 0.643831551f, 0.641481042f, 0.639124453f, 0.636761844f, + 0.634393275f, 0.632018745f, 0.629638255f, 0.627251804f, 0.624859512f, 0.622461259f, + 0.620057225f, 0.617647290f, 0.615231574f, 0.612810075f, 0.610382795f, 0.607949793f, + 0.605511069f, 0.603066623f, 0.600616455f, 0.598160684f, 0.595699310f, 0.593232274f, + 0.590759695f, 0.588281572f, 0.585797846f, 0.583308637f, 0.580813944f, 0.578313768f, + 0.575808167f, 0.573297143f, 0.570780754f, 0.568258941f, 0.565731823f, 0.563199341f, + 0.560661554f, 0.558118522f, 0.555570245f, 0.553016722f, 0.550457954f, 0.547894061f, + 0.545324981f, 0.542750776f, 0.540171444f, 0.537587047f, 0.534997642f, 0.532403111f, + 0.529803634f, 0.527199149f, 0.524589658f, 0.521975279f, 0.519356012f, 0.516731799f, + 0.514102757f, 0.511468828f, 0.508830130f, 0.506186664f, 0.503538370f, 0.500885367f, + 0.498227656f, 0.495565265f, 0.492898196f, 0.490226477f, 0.487550169f, 0.484869242f, + 0.482183784f, 0.479493767f, 0.476799220f, 0.474100202f, 0.471396744f, 0.468688816f, + 0.465976506f, 0.463259786f, 0.460538715f, 0.457813293f, 0.455083579f, 0.452349573f, + 0.449611336f, 0.446868837f, 0.444122136f, 0.441371262f, 0.438616246f, 0.435857087f, + 0.433093816f, 0.430326492f, 0.427555084f, 0.424779683f, 0.422000259f, 0.419216901f, + 0.416429549f, 0.413638324f, 0.410843164f, 0.408044159f, 0.405241311f, 0.402434647f, + 0.399624199f, 0.396809995f, 0.393992037f, 0.391170382f, 0.388345033f, 0.385516047f, + 0.382683426f, 0.379847199f, 0.377007425f, 0.374164075f, 0.371317208f, 0.368466824f, + 0.365612984f, 0.362755716f, 0.359895051f, 0.357030958f, 0.354163527f, 0.351292759f, + 0.348418683f, 0.345541328f, 0.342660725f, 0.339776874f, 0.336889863f, 0.333999664f, + 0.331106305f, 0.328209847f, 0.325310290f, 0.322407693f, 0.319502026f, 0.316593379f, + 0.313681751f, 0.310767144f, 0.307849646f, 0.304929227f, 0.302005947f, 0.299079835f, + 0.296150893f, 0.293219149f, 0.290284663f, 0.287347466f, 0.284407526f, 0.281464934f, + 0.278519690f, 0.275571823f, 0.272621363f, 0.269668311f, 0.266712755f, 0.263754666f, + 0.260794103f, 0.257831097f, 0.254865646f, 0.251897812f, 0.248927608f, 0.245955050f, + 0.242980182f, 0.240003020f, 0.237023607f, 0.234041959f, 0.231058106f, 0.228072077f, + 0.225083917f, 0.222093627f, 0.219101235f, 0.216106802f, 0.213110313f, 0.210111842f, + 0.207111374f, 0.204108968f, 0.201104641f, 0.198098406f, 0.195090324f, 0.192080393f, + 0.189068660f, 0.186055154f, 0.183039889f, 0.180022895f, 0.177004218f, 0.173983872f, + 0.170961887f, 0.167938292f, 0.164913118f, 0.161886394f, 0.158858150f, 0.155828401f, + 0.152797192f, 0.149764538f, 0.146730468f, 0.143695027f, 0.140658244f, 0.137620121f, + 0.134580702f, 0.131540030f, 0.128498107f, 0.125454977f, 0.122410677f, 0.119365215f, + 0.116318628f, 0.113270953f, 0.110222206f, 0.107172422f, 0.104121633f, 0.101069860f, + 0.098017141f, 0.094963498f, 0.091908954f, 0.088853553f, 0.085797310f, 0.082740262f, + 0.079682440f, 0.076623864f, 0.073564567f, 0.070504576f, 0.067443922f, 0.064382628f, + 0.061320737f, 0.058258265f, 0.055195246f, 0.052131705f, 0.049067676f, 0.046003181f, + 0.042938258f, 0.039872926f, 0.036807224f, 0.033741172f, 0.030674804f, 0.027608145f, + 0.024541229f, 0.021474080f, 0.018406730f, 0.015339206f, 0.012271538f, 0.009203754f, + 0.006135885f, 0.003067957f}, + {-0.000000000f, -0.003067957f, -0.006135885f, -0.009203754f, -0.012271538f, -0.015339206f, + -0.018406730f, -0.021474080f, -0.024541229f, -0.027608145f, -0.030674804f, -0.033741172f, + -0.036807224f, -0.039872926f, -0.042938258f, -0.046003181f, -0.049067676f, -0.052131705f, + -0.055195246f, -0.058258265f, -0.061320737f, -0.064382628f, -0.067443922f, -0.070504576f, + -0.073564567f, -0.076623864f, -0.079682440f, -0.082740262f, -0.085797310f, -0.088853553f, + -0.091908954f, -0.094963498f, -0.098017141f, -0.101069860f, -0.104121633f, -0.107172422f, + -0.110222206f, -0.113270953f, -0.116318628f, -0.119365215f, -0.122410677f, -0.125454977f, + -0.128498107f, -0.131540030f, -0.134580702f, -0.137620121f, -0.140658244f, -0.143695027f, + -0.146730468f, -0.149764538f, -0.152797192f, -0.155828401f, -0.158858150f, -0.161886394f, + -0.164913118f, -0.167938292f, -0.170961887f, -0.173983872f, -0.177004218f, -0.180022895f, + -0.183039889f, -0.186055154f, -0.189068660f, -0.192080393f, -0.195090324f, -0.198098406f, + -0.201104641f, -0.204108968f, -0.207111374f, -0.210111842f, -0.213110313f, -0.216106802f, + -0.219101235f, -0.222093627f, -0.225083917f, -0.228072077f, -0.231058106f, -0.234041959f, + -0.237023607f, -0.240003020f, -0.242980182f, -0.245955050f, -0.248927608f, -0.251897812f, + -0.254865646f, -0.257831097f, -0.260794103f, -0.263754666f, -0.266712755f, -0.269668311f, + -0.272621363f, -0.275571823f, -0.278519690f, -0.281464934f, -0.284407526f, -0.287347466f, + -0.290284663f, -0.293219149f, -0.296150893f, -0.299079835f, -0.302005947f, -0.304929227f, + -0.307849646f, -0.310767144f, -0.313681751f, -0.316593379f, -0.319502026f, -0.322407693f, + -0.325310290f, -0.328209847f, -0.331106305f, -0.333999664f, -0.336889863f, -0.339776874f, + -0.342660725f, -0.345541328f, -0.348418683f, -0.351292759f, -0.354163527f, -0.357030958f, + -0.359895051f, -0.362755716f, -0.365612984f, -0.368466824f, -0.371317208f, -0.374164075f, + -0.377007425f, -0.379847199f, -0.382683426f, -0.385516047f, -0.388345033f, -0.391170382f, + -0.393992037f, -0.396809995f, -0.399624199f, -0.402434647f, -0.405241311f, -0.408044159f, + -0.410843164f, -0.413638324f, -0.416429549f, -0.419216901f, -0.422000259f, -0.424779683f, + -0.427555084f, -0.430326492f, -0.433093816f, -0.435857087f, -0.438616246f, -0.441371262f, + -0.444122136f, -0.446868837f, -0.449611336f, -0.452349573f, -0.455083579f, -0.457813293f, + -0.460538715f, -0.463259786f, -0.465976506f, -0.468688816f, -0.471396744f, -0.474100202f, + -0.476799220f, -0.479493767f, -0.482183784f, -0.484869242f, -0.487550169f, -0.490226477f, + -0.492898196f, -0.495565265f, -0.498227656f, -0.500885367f, -0.503538370f, -0.506186664f, + -0.508830130f, -0.511468828f, -0.514102757f, -0.516731799f, -0.519356012f, -0.521975279f, + -0.524589658f, -0.527199149f, -0.529803634f, -0.532403111f, -0.534997642f, -0.537587047f, + -0.540171444f, -0.542750776f, -0.545324981f, -0.547894061f, -0.550457954f, -0.553016722f, + -0.555570245f, -0.558118522f, -0.560661554f, -0.563199341f, -0.565731823f, -0.568258941f, + -0.570780754f, -0.573297143f, -0.575808167f, -0.578313768f, -0.580813944f, -0.583308637f, + -0.585797846f, -0.588281572f, -0.590759695f, -0.593232274f, -0.595699310f, -0.598160684f, + -0.600616455f, -0.603066623f, -0.605511069f, -0.607949793f, -0.610382795f, -0.612810075f, + -0.615231574f, -0.617647290f, -0.620057225f, -0.622461259f, -0.624859512f, -0.627251804f, + -0.629638255f, -0.632018745f, -0.634393275f, -0.636761844f, -0.639124453f, -0.641481042f, + -0.643831551f, -0.646176040f, -0.648514390f, -0.650846660f, -0.653172851f, -0.655492842f, + -0.657806695f, -0.660114348f, -0.662415802f, -0.664710999f, -0.666999936f, -0.669282615f, + -0.671558976f, -0.673829019f, -0.676092684f, -0.678350031f, -0.680601001f, -0.682845533f, + -0.685083687f, -0.687315345f, -0.689540565f, -0.691759229f, -0.693971455f, -0.696177125f, + -0.698376238f, -0.700568795f, -0.702754736f, -0.704934061f, -0.707106769f, -0.709272802f, + -0.711432219f, -0.713584840f, -0.715730846f, -0.717870057f, -0.720002532f, -0.722128212f, + -0.724247098f, -0.726359129f, -0.728464365f, -0.730562747f, -0.732654274f, -0.734738886f, + -0.736816585f, -0.738887310f, -0.740951121f, -0.743007958f, -0.745057762f, -0.747100592f, + -0.749136388f, -0.751165152f, -0.753186822f, -0.755201399f, -0.757208824f, -0.759209216f, + -0.761202395f, -0.763188422f, -0.765167236f, -0.767138898f, -0.769103348f, -0.771060526f, + -0.773010433f, -0.774953127f, -0.776888490f, -0.778816521f, -0.780737221f, -0.782650590f, + -0.784556568f, -0.786455214f, -0.788346410f, -0.790230215f, -0.792106569f, -0.793975472f, + -0.795836926f, -0.797690868f, -0.799537241f, -0.801376164f, -0.803207517f, -0.805031359f, + -0.806847572f, -0.808656156f, -0.810457170f, -0.812250614f, -0.814036310f, -0.815814435f, + -0.817584813f, -0.819347501f, -0.821102500f, -0.822849810f, -0.824589312f, -0.826321065f, + -0.828045070f, -0.829761207f, -0.831469595f, -0.833170176f, -0.834862888f, -0.836547732f, + -0.838224709f, -0.839893818f, -0.841554999f, -0.843208253f, -0.844853580f, -0.846490920f, + -0.848120332f, -0.849741757f, -0.851355195f, -0.852960587f, -0.854557991f, -0.856147349f, + -0.857728601f, -0.859301805f, -0.860866964f, -0.862423956f, -0.863972843f, -0.865513623f, + -0.867046237f, -0.868570685f, -0.870086968f, -0.871595085f, -0.873094976f, -0.874586642f, + -0.876070082f, -0.877545297f, -0.879012227f, -0.880470872f, -0.881921291f, -0.883363366f, + -0.884797096f, -0.886222541f, -0.887639642f, -0.889048338f, -0.890448749f, -0.891840696f, + -0.893224299f, -0.894599497f, -0.895966232f, -0.897324562f, -0.898674488f, -0.900015891f, + -0.901348829f, -0.902673304f, -0.903989315f, -0.905296743f, -0.906595707f, -0.907886088f, + -0.909168005f, -0.910441279f, -0.911706030f, -0.912962198f, -0.914209783f, -0.915448725f, + -0.916679084f, -0.917900801f, -0.919113874f, -0.920318305f, -0.921514034f, -0.922701120f, + -0.923879504f, -0.925049245f, -0.926210225f, -0.927362502f, -0.928506076f, -0.929640889f, + -0.930766940f, -0.931884289f, -0.932992816f, -0.934092522f, -0.935183525f, -0.936265647f, + -0.937339008f, -0.938403547f, -0.939459205f, -0.940506041f, -0.941544056f, -0.942573190f, + -0.943593442f, -0.944604814f, -0.945607305f, -0.946600914f, -0.947585583f, -0.948561370f, + -0.949528158f, -0.950486064f, -0.951435030f, -0.952374995f, -0.953306019f, -0.954228103f, + -0.955141187f, -0.956045270f, -0.956940353f, -0.957826436f, -0.958703458f, -0.959571540f, + -0.960430503f, -0.961280465f, -0.962121427f, -0.962953269f, -0.963776052f, -0.964589775f, + -0.965394437f, -0.966189981f, -0.966976464f, -0.967753828f, -0.968522072f, -0.969281256f, + -0.970031261f, -0.970772147f, -0.971503913f, -0.972226501f, -0.972939968f, -0.973644257f, + -0.974339366f, -0.975025356f, -0.975702107f, -0.976369739f, -0.977028131f, -0.977677345f, + -0.978317380f, -0.978948176f, -0.979569793f, -0.980182111f, -0.980785251f, -0.981379211f, + -0.981963873f, -0.982539296f, -0.983105481f, -0.983662426f, -0.984210074f, -0.984748483f, + -0.985277653f, -0.985797524f, -0.986308098f, -0.986809373f, -0.987301409f, -0.987784147f, + -0.988257587f, -0.988721669f, -0.989176512f, -0.989621997f, -0.990058184f, -0.990485072f, + -0.990902662f, -0.991310835f, -0.991709769f, -0.992099285f, -0.992479563f, -0.992850423f, + -0.993211925f, -0.993564129f, -0.993906975f, -0.994240463f, -0.994564593f, -0.994879305f, + -0.995184720f, -0.995480776f, -0.995767415f, -0.996044695f, -0.996312618f, -0.996571124f, + -0.996820271f, -0.997060061f, -0.997290432f, -0.997511446f, -0.997723043f, -0.997925282f, + -0.998118103f, -0.998301566f, -0.998475552f, -0.998640239f, -0.998795450f, -0.998941302f, + -0.999077737f, -0.999204755f, -0.999322355f, -0.999430597f, -0.999529421f, -0.999618828f, + -0.999698818f, -0.999769390f, -0.999830604f, -0.999882340f, -0.999924719f, -0.999957621f, + -0.999981165f, -0.999995291f}}; + +const FLOAT32 iusace_pre_post_twid_cos_sin_256[4][256] = { + { + 0.9999988079f, 0.9999706149f, 0.9999046922f, 0.9998011589f, 0.9996600151f, 0.9994812012f, + 0.9992647767f, 0.9990106821f, 0.9987190366f, 0.9983897209f, 0.9980228543f, 0.9976184368f, + 0.9971764088f, 0.9966968894f, 0.9961798191f, 0.9956252575f, 0.9950332046f, 0.9944036603f, + 0.9937367439f, 0.9930323362f, 0.9922906160f, 0.9915114641f, 0.9906949997f, 0.9898412824f, + 0.9889502525f, 0.9880220294f, 0.9870565534f, 0.9860539436f, 0.9850142598f, 0.9839374423f, + 0.9828235507f, 0.9816727042f, 0.9804848433f, 0.9792601466f, 0.9779984951f, 0.9767000675f, + 0.9753648639f, 0.9739929438f, 0.9725843668f, 0.9711391330f, 0.9696573615f, 0.9681391120f, + 0.9665843844f, 0.9649932384f, 0.9633657932f, 0.9617020488f, 0.9600021243f, 0.9582660794f, + 0.9564939141f, 0.9546857476f, 0.9528416395f, 0.9509616494f, 0.9490458965f, 0.9470943809f, + 0.9451072216f, 0.9430844188f, 0.9410261512f, 0.9389324784f, 0.9368034601f, 0.9346391559f, + 0.9324396253f, 0.9302050471f, 0.9279354215f, 0.9256308079f, 0.9232914448f, 0.9209172130f, + 0.9185084105f, 0.9160649776f, 0.9135870337f, 0.9110747576f, 0.9085280895f, 0.9059472680f, + 0.9033323526f, 0.9006834030f, 0.8980005980f, 0.8952839375f, 0.8925335407f, 0.8897495866f, + 0.8869321346f, 0.8840812445f, 0.8811970949f, 0.8782798052f, 0.8753293753f, 0.8723460436f, + 0.8693298697f, 0.8662809730f, 0.8631994128f, 0.8600853682f, 0.8569389582f, 0.8537603021f, + 0.8505494595f, 0.8473066092f, 0.8440318704f, 0.8407253623f, 0.8373872042f, 0.8340175152f, + 0.8306164145f, 0.8271840215f, 0.8237205148f, 0.8202259541f, 0.8167005777f, 0.8131443858f, + 0.8095576167f, 0.8059403896f, 0.8022928238f, 0.7986149788f, 0.7949071527f, 0.7911693454f, + 0.7874017358f, 0.7836045027f, 0.7797777653f, 0.7759217024f, 0.7720363736f, 0.7681220174f, + 0.7641787529f, 0.7602066994f, 0.7562059760f, 0.7521768212f, 0.7481193542f, 0.7440337539f, + 0.7399200797f, 0.7357785702f, 0.7316094041f, 0.7274126410f, 0.7231884599f, 0.7189370990f, + 0.7146586776f, 0.7103533745f, 0.7060212493f, 0.7016626000f, 0.6972774863f, 0.6928661466f, + 0.6884287596f, 0.6839653850f, 0.6794763207f, 0.6749616265f, 0.6704215407f, 0.6658562422f, + 0.6612658501f, 0.6566505432f, 0.6520105600f, 0.6473459601f, 0.6426570415f, 0.6379439235f, + 0.6332067847f, 0.6284457445f, 0.6236611009f, 0.6188529730f, 0.6140215397f, 0.6091670394f, + 0.6042895317f, 0.5993893147f, 0.5944665074f, 0.5895212889f, 0.5845539570f, 0.5795645714f, + 0.5745533705f, 0.5695205331f, 0.5644662380f, 0.5593907237f, 0.5542941093f, 0.5491766334f, + 0.5440385342f, 0.5388799310f, 0.5337010026f, 0.5285019875f, 0.5232831240f, 0.5180445313f, + 0.5127863884f, 0.5075089931f, 0.5022124648f, 0.4968970418f, 0.4915629029f, 0.4862102866f, + 0.4808393419f, 0.4754502773f, 0.4700433314f, 0.4646186829f, 0.4591765404f, 0.4537171125f, + 0.4482406080f, 0.4427472353f, 0.4372371733f, 0.4317106605f, 0.4261678755f, 0.4206090868f, + 0.4150344133f, 0.4094441533f, 0.4038384557f, 0.3982175589f, 0.3925816715f, 0.3869310021f, + 0.3812657595f, 0.3755861819f, 0.3698924482f, 0.3641847968f, 0.3584634066f, 0.3527285457f, + 0.3469804227f, 0.3412192166f, 0.3354451358f, 0.3296584487f, 0.3238593638f, 0.3180480897f, + 0.3122248054f, 0.3063898087f, 0.3005432487f, 0.2946853638f, 0.2888164222f, 0.2829365730f, + 0.2770460844f, 0.2711451650f, 0.2652340233f, 0.2593129277f, 0.2533820271f, 0.2474416196f, + 0.2414918840f, 0.2355330586f, 0.2295653671f, 0.2235890329f, 0.2176042795f, 0.2116113305f, + 0.2056104094f, 0.1996017545f, 0.1935855895f, 0.1875621229f, 0.1815316081f, 0.1754942536f, + 0.1694502980f, 0.1633999497f, 0.1573434621f, 0.1512810439f, 0.1452129185f, 0.1391393393f, + 0.1330605298f, 0.1269766986f, 0.1208880842f, 0.1147949249f, 0.1086974442f, 0.1025958657f, + 0.0964904279f, 0.0903813615f, 0.0842688903f, 0.0781532452f, 0.0720346496f, 0.0659133494f, + 0.0597895719f, 0.0536635369f, 0.0475354828f, 0.0414056405f, 0.0352742374f, 0.0291415080f, + 0.0230076816f, 0.0168729872f, 0.0107376594f, 0.0046019261f, + }, + // sine tables + { + -0.0015339801f, -0.0076698288f, -0.0138053885f, -0.0199404284f, -0.0260747187f, + -0.0322080255f, -0.0383401215f, -0.0444707721f, -0.0505997501f, -0.0567268208f, + -0.0628517568f, -0.0689743310f, -0.0750942975f, -0.0812114477f, -0.0873255357f, + -0.0934363380f, -0.0995436162f, -0.1056471542f, -0.1117467135f, -0.1178420633f, + -0.1239329726f, -0.1300192177f, -0.1361005753f, -0.1421768069f, -0.1482476741f, + -0.1543129683f, -0.1603724509f, -0.1664258987f, -0.1724730879f, -0.1785137653f, + -0.1845477372f, -0.1905747503f, -0.1965945959f, -0.2026070356f, -0.2086118460f, + -0.2146088183f, -0.2205976844f, -0.2265782654f, -0.2325503081f, -0.2385135889f, + -0.2444678992f, -0.2504130006f, -0.2563486695f, -0.2622747123f, -0.2681908607f, + -0.2740969062f, -0.2799926400f, -0.2858778238f, -0.2917522490f, -0.2976157069f, + -0.3034679592f, -0.3093087673f, -0.3151379228f, -0.3209552467f, -0.3267604411f, + -0.3325533569f, -0.3383337557f, -0.3441014290f, -0.3498561382f, -0.3555976748f, + -0.3613258004f, -0.3670403361f, -0.3727410734f, -0.3784277439f, -0.3841001987f, + -0.3897581697f, -0.3954014778f, -0.4010298848f, -0.4066432118f, -0.4122412205f, + -0.4178237021f, -0.4233904779f, -0.4289412796f, -0.4344759583f, -0.4399942756f, + -0.4454960227f, -0.4509809911f, -0.4564489722f, -0.4618997872f, -0.4673331976f, + -0.4727490246f, -0.4781470597f, -0.4835270643f, -0.4888888896f, -0.4942322969f, + -0.4995571077f, -0.5048630834f, -0.5101500750f, -0.5154178739f, -0.5206662416f, + -0.5258949995f, -0.5311040282f, -0.5362929702f, -0.5414617658f, -0.5466101766f, + -0.5517379642f, -0.5568450093f, -0.5619311333f, -0.5669960380f, -0.5720396042f, + -0.5770616531f, -0.5820620060f, -0.5870403647f, -0.5919966698f, -0.5969306827f, + -0.6018422246f, -0.6067311168f, -0.6115971804f, -0.6164401770f, -0.6212599874f, + -0.6260563731f, -0.6308292150f, -0.6355783343f, -0.6403034925f, -0.6450045109f, + -0.6496813297f, -0.6543335915f, -0.6589612961f, -0.6635641456f, -0.6681420207f, + -0.6726947427f, -0.6772221923f, -0.6817240715f, -0.6862003207f, -0.6906507015f, + -0.6950750947f, -0.6994733214f, -0.7038452625f, -0.7081906199f, -0.7125093937f, + -0.7168012857f, -0.7210661769f, -0.7253039479f, -0.7295144200f, -0.7336974144f, + -0.7378528118f, -0.7419804335f, -0.7460801005f, -0.7501516342f, -0.7541949749f, + -0.7582098842f, -0.7621963024f, -0.7661539912f, -0.7700828314f, -0.7739827037f, + -0.7778534293f, -0.7816948295f, -0.7855068445f, -0.7892892361f, -0.7930419445f, + -0.7967647910f, -0.8004576564f, -0.8041203618f, -0.8077528477f, -0.8113548756f, + -0.8149263263f, -0.8184671402f, -0.8219771385f, -0.8254561424f, -0.8289040923f, + -0.8323208690f, -0.8357062936f, -0.8390602469f, -0.8423826098f, -0.8456732631f, + -0.8489320278f, -0.8521589041f, -0.8553536534f, -0.8585162163f, -0.8616464734f, + -0.8647442460f, -0.8678094745f, -0.8708420396f, -0.8738418221f, -0.8768087029f, + -0.8797426224f, -0.8826433420f, -0.8855108619f, -0.8883450627f, -0.8911457658f, + -0.8939129710f, -0.8966464996f, -0.8993462324f, -0.9020121694f, -0.9046440721f, + -0.9072420001f, -0.9098057151f, -0.9123351574f, -0.9148303270f, -0.9172909856f, + -0.9197171330f, -0.9221086502f, -0.9244654775f, -0.9267874956f, -0.9290745854f, + -0.9313266873f, -0.9335438013f, -0.9357256889f, -0.9378723502f, -0.9399837255f, + -0.9420597553f, -0.9441002607f, -0.9461052418f, -0.9480745792f, -0.9500082731f, + -0.9519061446f, -0.9537681937f, -0.9555943608f, -0.9573845267f, -0.9591386318f, + -0.9608566165f, -0.9625384808f, -0.9641840458f, -0.9657933712f, -0.9673662782f, + -0.9689028263f, -0.9704028368f, -0.9718663096f, -0.9732932448f, -0.9746835232f, + -0.9760370851f, -0.9773538709f, -0.9786339402f, -0.9798771143f, -0.9810833931f, + -0.9822527170f, -0.9833850861f, -0.9844804406f, -0.9855387211f, -0.9865599275f, + -0.9875439405f, -0.9884908199f, -0.9894004464f, -0.9902728200f, -0.9911079407f, + -0.9919056892f, -0.9926661253f, -0.9933891892f, -0.9940748811f, -0.9947231412f, + -0.9953339100f, -0.9959072471f, -0.9964430332f, -0.9969413280f, -0.9974021316f, + -0.9978253245f, -0.9982110262f, -0.9985590577f, -0.9988695383f, -0.9991424084f, + -0.9993776679f, -0.9995753169f, -0.9997352958f, -0.9998576641f, -0.9999423623f, + -0.9999893904f, + }, + { + 1.0000000000f, 0.9999811649f, 0.9999247193f, 0.9998306036f, 0.9996988177f, 0.9995294213f, + 0.9993223548f, 0.9990777373f, 0.9987954497f, 0.9984755516f, 0.9981181026f, 0.9977230430f, + 0.9972904325f, 0.9968202710f, 0.9963126183f, 0.9957674146f, 0.9951847196f, 0.9945645928f, + 0.9939069748f, 0.9932119250f, 0.9924795628f, 0.9917097688f, 0.9909026623f, 0.9900581837f, + 0.9891765118f, 0.9882575870f, 0.9873014092f, 0.9863080978f, 0.9852776527f, 0.9842100739f, + 0.9831054807f, 0.9819638729f, 0.9807852507f, 0.9795697927f, 0.9783173800f, 0.9770281315f, + 0.9757021070f, 0.9743393660f, 0.9729399681f, 0.9715039134f, 0.9700312614f, 0.9685220718f, + 0.9669764638f, 0.9653944373f, 0.9637760520f, 0.9621214271f, 0.9604305029f, 0.9587034583f, + 0.9569403529f, 0.9551411867f, 0.9533060193f, 0.9514350295f, 0.9495281577f, 0.9475855827f, + 0.9456073046f, 0.9435934424f, 0.9415440559f, 0.9394592047f, 0.9373390079f, 0.9351835251f, + 0.9329928160f, 0.9307669401f, 0.9285060763f, 0.9262102246f, 0.9238795042f, 0.9215140343f, + 0.9191138744f, 0.9166790843f, 0.9142097831f, 0.9117060304f, 0.9091680050f, 0.9065957069f, + 0.9039893150f, 0.9013488293f, 0.8986744881f, 0.8959662318f, 0.8932242990f, 0.8904487491f, + 0.8876396418f, 0.8847970963f, 0.8819212914f, 0.8790122271f, 0.8760700822f, 0.8730949759f, + 0.8700869679f, 0.8670462370f, 0.8639728427f, 0.8608669639f, 0.8577286005f, 0.8545579910f, + 0.8513551950f, 0.8481203318f, 0.8448535800f, 0.8415549994f, 0.8382247090f, 0.8348628879f, + 0.8314695954f, 0.8280450702f, 0.8245893121f, 0.8211025000f, 0.8175848126f, 0.8140363097f, + 0.8104571700f, 0.8068475723f, 0.8032075167f, 0.7995372415f, 0.7958369255f, 0.7921065688f, + 0.7883464098f, 0.7845565677f, 0.7807372212f, 0.7768884897f, 0.7730104327f, 0.7691033483f, + 0.7651672363f, 0.7612023950f, 0.7572088242f, 0.7531868219f, 0.7491363883f, 0.7450577617f, + 0.7409511209f, 0.7368165851f, 0.7326542735f, 0.7284643650f, 0.7242470980f, 0.7200025320f, + 0.7157308459f, 0.7114322186f, 0.7071067691f, 0.7027547359f, 0.6983762383f, 0.6939714551f, + 0.6895405650f, 0.6850836873f, 0.6806010008f, 0.6760926843f, 0.6715589762f, 0.6669999361f, + 0.6624158025f, 0.6578066945f, 0.6531728506f, 0.6485143900f, 0.6438315511f, 0.6391244531f, + 0.6343932748f, 0.6296382546f, 0.6248595119f, 0.6200572252f, 0.6152315736f, 0.6103827953f, + 0.6055110693f, 0.6006164551f, 0.5956993103f, 0.5907596946f, 0.5857978463f, 0.5808139443f, + 0.5758081675f, 0.5707807541f, 0.5657318234f, 0.5606615543f, 0.5555702448f, 0.5504579544f, + 0.5453249812f, 0.5401714444f, 0.5349976420f, 0.5298036337f, 0.5245896578f, 0.5193560123f, + 0.5141027570f, 0.5088301301f, 0.5035383701f, 0.4982276559f, 0.4928981960f, 0.4875501692f, + 0.4821837842f, 0.4767992198f, 0.4713967443f, 0.4659765065f, 0.4605387151f, 0.4550835788f, + 0.4496113360f, 0.4441221356f, 0.4386162460f, 0.4330938160f, 0.4275550842f, 0.4220002592f, + 0.4164295495f, 0.4108431637f, 0.4052413106f, 0.3996241987f, 0.3939920366f, 0.3883450329f, + 0.3826834261f, 0.3770074248f, 0.3713172078f, 0.3656129837f, 0.3598950505f, 0.3541635275f, + 0.3484186828f, 0.3426607251f, 0.3368898630f, 0.3311063051f, 0.3253102899f, 0.3195020258f, + 0.3136817515f, 0.3078496456f, 0.3020059466f, 0.2961508930f, 0.2902846634f, 0.2844075263f, + 0.2785196900f, 0.2726213634f, 0.2667127550f, 0.2607941031f, 0.2548656464f, 0.2489276081f, + 0.2429801822f, 0.2370236069f, 0.2310581058f, 0.2250839174f, 0.2191012353f, 0.2131103128f, + 0.2071113735f, 0.2011046410f, 0.1950903237f, 0.1890686601f, 0.1830398887f, 0.1770042181f, + 0.1709618866f, 0.1649131179f, 0.1588581502f, 0.1527971923f, 0.1467304677f, 0.1406582445f, + 0.1345807016f, 0.1284981072f, 0.1224106774f, 0.1163186282f, 0.1102222055f, 0.1041216329f, + 0.0980171412f, 0.0919089541f, 0.0857973099f, 0.0796824396f, 0.0735645667f, 0.0674439222f, + 0.0613207370f, 0.0551952459f, 0.0490676761f, 0.0429382585f, 0.0368072242f, 0.0306748040f, + 0.0245412290f, 0.0184067301f, 0.0122715384f, 0.0061358847f, + }, + { + -0.0000000000f, -0.0061358847f, -0.0122715384f, -0.0184067301f, -0.0245412290f, + -0.0306748040f, -0.0368072242f, -0.0429382585f, -0.0490676761f, -0.0551952459f, + -0.0613207370f, -0.0674439222f, -0.0735645667f, -0.0796824396f, -0.0857973099f, + -0.0919089541f, -0.0980171412f, -0.1041216329f, -0.1102222055f, -0.1163186282f, + -0.1224106774f, -0.1284981072f, -0.1345807016f, -0.1406582445f, -0.1467304677f, + -0.1527971923f, -0.1588581502f, -0.1649131179f, -0.1709618866f, -0.1770042181f, + -0.1830398887f, -0.1890686601f, -0.1950903237f, -0.2011046410f, -0.2071113735f, + -0.2131103128f, -0.2191012353f, -0.2250839174f, -0.2310581058f, -0.2370236069f, + -0.2429801822f, -0.2489276081f, -0.2548656464f, -0.2607941031f, -0.2667127550f, + -0.2726213634f, -0.2785196900f, -0.2844075263f, -0.2902846634f, -0.2961508930f, + -0.3020059466f, -0.3078496456f, -0.3136817515f, -0.3195020258f, -0.3253102899f, + -0.3311063051f, -0.3368898630f, -0.3426607251f, -0.3484186828f, -0.3541635275f, + -0.3598950505f, -0.3656129837f, -0.3713172078f, -0.3770074248f, -0.3826834261f, + -0.3883450329f, -0.3939920366f, -0.3996241987f, -0.4052413106f, -0.4108431637f, + -0.4164295495f, -0.4220002592f, -0.4275550842f, -0.4330938160f, -0.4386162460f, + -0.4441221356f, -0.4496113360f, -0.4550835788f, -0.4605387151f, -0.4659765065f, + -0.4713967443f, -0.4767992198f, -0.4821837842f, -0.4875501692f, -0.4928981960f, + -0.4982276559f, -0.5035383701f, -0.5088301301f, -0.5141027570f, -0.5193560123f, + -0.5245896578f, -0.5298036337f, -0.5349976420f, -0.5401714444f, -0.5453249812f, + -0.5504579544f, -0.5555702448f, -0.5606615543f, -0.5657318234f, -0.5707807541f, + -0.5758081675f, -0.5808139443f, -0.5857978463f, -0.5907596946f, -0.5956993103f, + -0.6006164551f, -0.6055110693f, -0.6103827953f, -0.6152315736f, -0.6200572252f, + -0.6248595119f, -0.6296382546f, -0.6343932748f, -0.6391244531f, -0.6438315511f, + -0.6485143900f, -0.6531728506f, -0.6578066945f, -0.6624158025f, -0.6669999361f, + -0.6715589762f, -0.6760926843f, -0.6806010008f, -0.6850836873f, -0.6895405650f, + -0.6939714551f, -0.6983762383f, -0.7027547359f, -0.7071067691f, -0.7114322186f, + -0.7157308459f, -0.7200025320f, -0.7242470980f, -0.7284643650f, -0.7326542735f, + -0.7368165851f, -0.7409511209f, -0.7450577617f, -0.7491363883f, -0.7531868219f, + -0.7572088242f, -0.7612023950f, -0.7651672363f, -0.7691033483f, -0.7730104327f, + -0.7768884897f, -0.7807372212f, -0.7845565677f, -0.7883464098f, -0.7921065688f, + -0.7958369255f, -0.7995372415f, -0.8032075167f, -0.8068475723f, -0.8104571700f, + -0.8140363097f, -0.8175848126f, -0.8211025000f, -0.8245893121f, -0.8280450702f, + -0.8314695954f, -0.8348628879f, -0.8382247090f, -0.8415549994f, -0.8448535800f, + -0.8481203318f, -0.8513551950f, -0.8545579910f, -0.8577286005f, -0.8608669639f, + -0.8639728427f, -0.8670462370f, -0.8700869679f, -0.8730949759f, -0.8760700822f, + -0.8790122271f, -0.8819212914f, -0.8847970963f, -0.8876396418f, -0.8904487491f, + -0.8932242990f, -0.8959662318f, -0.8986744881f, -0.9013488293f, -0.9039893150f, + -0.9065957069f, -0.9091680050f, -0.9117060304f, -0.9142097831f, -0.9166790843f, + -0.9191138744f, -0.9215140343f, -0.9238795042f, -0.9262102246f, -0.9285060763f, + -0.9307669401f, -0.9329928160f, -0.9351835251f, -0.9373390079f, -0.9394592047f, + -0.9415440559f, -0.9435934424f, -0.9456073046f, -0.9475855827f, -0.9495281577f, + -0.9514350295f, -0.9533060193f, -0.9551411867f, -0.9569403529f, -0.9587034583f, + -0.9604305029f, -0.9621214271f, -0.9637760520f, -0.9653944373f, -0.9669764638f, + -0.9685220718f, -0.9700312614f, -0.9715039134f, -0.9729399681f, -0.9743393660f, + -0.9757021070f, -0.9770281315f, -0.9783173800f, -0.9795697927f, -0.9807852507f, + -0.9819638729f, -0.9831054807f, -0.9842100739f, -0.9852776527f, -0.9863080978f, + -0.9873014092f, -0.9882575870f, -0.9891765118f, -0.9900581837f, -0.9909026623f, + -0.9917097688f, -0.9924795628f, -0.9932119250f, -0.9939069748f, -0.9945645928f, + -0.9951847196f, -0.9957674146f, -0.9963126183f, -0.9968202710f, -0.9972904325f, + -0.9977230430f, -0.9981181026f, -0.9984755516f, -0.9987954497f, -0.9990777373f, + -0.9993223548f, -0.9995294213f, -0.9996988177f, -0.9998306036f, -0.9999247193f, + -0.9999811649f, + }}; + +const FLOAT32 iusace_pre_post_twid_cos_sin_128[4][128] = { + { + 0.9999952912f, 0.9998823404f, 0.9996188283f, 0.9992047548f, 0.9986402392f, 0.9979252815f, + 0.9970600605f, 0.9960446954f, 0.9948793054f, 0.9935641289f, 0.9920992851f, 0.9904850721f, + 0.9887216687f, 0.9868093729f, 0.9847484827f, 0.9825392962f, 0.9801821113f, 0.9776773453f, + 0.9750253558f, 0.9722265005f, 0.9692812562f, 0.9661899805f, 0.9629532695f, 0.9595715404f, + 0.9560452700f, 0.9523749948f, 0.9485613704f, 0.9446048141f, 0.9405060410f, 0.9362656474f, + 0.9318842888f, 0.9273625016f, 0.9227011204f, 0.9179008007f, 0.9129621983f, 0.9078860879f, + 0.9026733041f, 0.8973245621f, 0.8918406963f, 0.8862225413f, 0.8804708719f, 0.8745866418f, + 0.8685706854f, 0.8624239564f, 0.8561473489f, 0.8497417569f, 0.8432082534f, 0.8365477324f, + 0.8297612071f, 0.8228498101f, 0.8158144355f, 0.8086561561f, 0.8013761640f, 0.7939754725f, + 0.7864552140f, 0.7788165212f, 0.7710605264f, 0.7631884217f, 0.7552013993f, 0.7471005917f, + 0.7388873100f, 0.7305627465f, 0.7221282125f, 0.7135848403f, 0.7049340606f, 0.6961771250f, + 0.6873153448f, 0.6783500314f, 0.6692826152f, 0.6601143479f, 0.6508466601f, 0.6414810419f, + 0.6320187449f, 0.6224612594f, 0.6128100753f, 0.6030666232f, 0.5932322741f, 0.5833086371f, + 0.5732971430f, 0.5631993413f, 0.5530167222f, 0.5427507758f, 0.5324031115f, 0.5219752789f, + 0.5114688277f, 0.5008853674f, 0.4902264774f, 0.4794937670f, 0.4686888158f, 0.4578132927f, + 0.4468688369f, 0.4358570874f, 0.4247796834f, 0.4136383235f, 0.4024346471f, 0.3911703825f, + 0.3798471987f, 0.3684668243f, 0.3570309579f, 0.3455413282f, 0.3339996636f, 0.3224076927f, + 0.3107671440f, 0.2990798354f, 0.2873474658f, 0.2755718231f, 0.2637546659f, 0.2518978119f, + 0.2400030196f, 0.2280720770f, 0.2161068022f, 0.2041089684f, 0.1920803934f, 0.1800228953f, + 0.1679382920f, 0.1558284014f, 0.1436950266f, 0.1315400302f, 0.1193652153f, 0.1071724221f, + 0.0949634984f, 0.0827402622f, 0.0705045760f, 0.0582582653f, 0.0460031815f, 0.0337411724f, + 0.0214740802f, 0.0092037544f, + }, + // sine tables + { + -0.0030679568f, -0.0153392060f, -0.0276081450f, -0.0398729257f, -0.0521317050f, + -0.0643826276f, -0.0766238645f, -0.0888535529f, -0.1010698602f, -0.1132709533f, + -0.1254549772f, -0.1376201212f, -0.1497645378f, -0.1618863940f, -0.1739838719f, + -0.1860551536f, -0.1980984062f, -0.2101118416f, -0.2220936269f, -0.2340419590f, + -0.2459550500f, -0.2578310966f, -0.2696683109f, -0.2814649343f, -0.2932191491f, + -0.3049292266f, -0.3165933788f, -0.3282098472f, -0.3397768736f, -0.3512927592f, + -0.3627557158f, -0.3741640747f, -0.3855160475f, -0.3968099952f, -0.4080441594f, + -0.4192169011f, -0.4303264916f, -0.4413712621f, -0.4523495734f, -0.4632597864f, + -0.4741002023f, -0.4848692417f, -0.4955652654f, -0.5061866641f, -0.5167317986f, + -0.5271991491f, -0.5375870466f, -0.5478940606f, -0.5581185222f, -0.5682589412f, + -0.5783137679f, -0.5882815719f, -0.5981606841f, -0.6079497933f, -0.6176472902f, + -0.6272518039f, -0.6367618442f, -0.6461760402f, -0.6554928422f, -0.6647109985f, + -0.6738290191f, -0.6828455329f, -0.6917592287f, -0.7005687952f, -0.7092728019f, + -0.7178700566f, -0.7263591290f, -0.7347388864f, -0.7430079579f, -0.7511651516f, + -0.7592092156f, -0.7671388984f, -0.7749531269f, -0.7826505899f, -0.7902302146f, + -0.7976908684f, -0.8050313592f, -0.8122506142f, -0.8193475008f, -0.8263210654f, + -0.8331701756f, -0.8398938179f, -0.8464909196f, -0.8529605865f, -0.8593018055f, + -0.8655136228f, -0.8715950847f, -0.8775452971f, -0.8833633661f, -0.8890483379f, + -0.8945994973f, -0.9000158906f, -0.9052967429f, -0.9104412794f, -0.9154487252f, + -0.9203183055f, -0.9250492454f, -0.9296408892f, -0.9340925217f, -0.9384035468f, + -0.9425731897f, -0.9466009140f, -0.9504860640f, -0.9542281032f, -0.9578264356f, + -0.9612804651f, -0.9645897746f, -0.9677538276f, -0.9707721472f, -0.9736442566f, + -0.9763697386f, -0.9789481759f, -0.9813792109f, -0.9836624265f, -0.9857975245f, + -0.9877841473f, -0.9896219969f, -0.9913108349f, -0.9928504229f, -0.9942404628f, + -0.9954807758f, -0.9965711236f, -0.9975114465f, -0.9983015656f, -0.9989413023f, + -0.9994305968f, -0.9997693896f, -0.9999576211f, + }, + { + 1.0000000000f, 0.9999247193f, 0.9996988177f, 0.9993223548f, 0.9987954497f, 0.9981181026f, + 0.9972904325f, 0.9963126183f, 0.9951847196f, 0.9939069748f, 0.9924795628f, 0.9909026623f, + 0.9891765118f, 0.9873014092f, 0.9852776527f, 0.9831054807f, 0.9807852507f, 0.9783173800f, + 0.9757021070f, 0.9729399681f, 0.9700312614f, 0.9669764638f, 0.9637760520f, 0.9604305029f, + 0.9569403529f, 0.9533060193f, 0.9495281577f, 0.9456073046f, 0.9415440559f, 0.9373390079f, + 0.9329928160f, 0.9285060763f, 0.9238795042f, 0.9191138744f, 0.9142097831f, 0.9091680050f, + 0.9039893150f, 0.8986744881f, 0.8932242990f, 0.8876396418f, 0.8819212914f, 0.8760700822f, + 0.8700869679f, 0.8639728427f, 0.8577286005f, 0.8513551950f, 0.8448535800f, 0.8382247090f, + 0.8314695954f, 0.8245893121f, 0.8175848126f, 0.8104571700f, 0.8032075167f, 0.7958369255f, + 0.7883464098f, 0.7807372212f, 0.7730104327f, 0.7651672363f, 0.7572088242f, 0.7491363883f, + 0.7409511209f, 0.7326542735f, 0.7242470980f, 0.7157308459f, 0.7071067691f, 0.6983762383f, + 0.6895405650f, 0.6806010008f, 0.6715589762f, 0.6624158025f, 0.6531728506f, 0.6438315511f, + 0.6343932748f, 0.6248595119f, 0.6152315736f, 0.6055110693f, 0.5956993103f, 0.5857978463f, + 0.5758081675f, 0.5657318234f, 0.5555702448f, 0.5453249812f, 0.5349976420f, 0.5245896578f, + 0.5141027570f, 0.5035383701f, 0.4928981960f, 0.4821837842f, 0.4713967443f, 0.4605387151f, + 0.4496113360f, 0.4386162460f, 0.4275550842f, 0.4164295495f, 0.4052413106f, 0.3939920366f, + 0.3826834261f, 0.3713172078f, 0.3598950505f, 0.3484186828f, 0.3368898630f, 0.3253102899f, + 0.3136817515f, 0.3020059466f, 0.2902846634f, 0.2785196900f, 0.2667127550f, 0.2548656464f, + 0.2429801822f, 0.2310581058f, 0.2191012353f, 0.2071113735f, 0.1950903237f, 0.1830398887f, + 0.1709618866f, 0.1588581502f, 0.1467304677f, 0.1345807016f, 0.1224106774f, 0.1102222055f, + 0.0980171412f, 0.0857973099f, 0.0735645667f, 0.0613207370f, 0.0490676761f, 0.0368072242f, + 0.0245412290f, 0.0122715384f, + }, + { + -0.0000000000f, -0.0122715384f, -0.0245412290f, -0.0368072242f, -0.0490676761f, + -0.0613207370f, -0.0735645667f, -0.0857973099f, -0.0980171412f, -0.1102222055f, + -0.1224106774f, -0.1345807016f, -0.1467304677f, -0.1588581502f, -0.1709618866f, + -0.1830398887f, -0.1950903237f, -0.2071113735f, -0.2191012353f, -0.2310581058f, + -0.2429801822f, -0.2548656464f, -0.2667127550f, -0.2785196900f, -0.2902846634f, + -0.3020059466f, -0.3136817515f, -0.3253102899f, -0.3368898630f, -0.3484186828f, + -0.3598950505f, -0.3713172078f, -0.3826834261f, -0.3939920366f, -0.4052413106f, + -0.4164295495f, -0.4275550842f, -0.4386162460f, -0.4496113360f, -0.4605387151f, + -0.4713967443f, -0.4821837842f, -0.4928981960f, -0.5035383701f, -0.5141027570f, + -0.5245896578f, -0.5349976420f, -0.5453249812f, -0.5555702448f, -0.5657318234f, + -0.5758081675f, -0.5857978463f, -0.5956993103f, -0.6055110693f, -0.6152315736f, + -0.6248595119f, -0.6343932748f, -0.6438315511f, -0.6531728506f, -0.6624158025f, + -0.6715589762f, -0.6806010008f, -0.6895405650f, -0.6983762383f, -0.7071067691f, + -0.7157308459f, -0.7242470980f, -0.7326542735f, -0.7409511209f, -0.7491363883f, + -0.7572088242f, -0.7651672363f, -0.7730104327f, -0.7807372212f, -0.7883464098f, + -0.7958369255f, -0.8032075167f, -0.8104571700f, -0.8175848126f, -0.8245893121f, + -0.8314695954f, -0.8382247090f, -0.8448535800f, -0.8513551950f, -0.8577286005f, + -0.8639728427f, -0.8700869679f, -0.8760700822f, -0.8819212914f, -0.8876396418f, + -0.8932242990f, -0.8986744881f, -0.9039893150f, -0.9091680050f, -0.9142097831f, + -0.9191138744f, -0.9238795042f, -0.9285060763f, -0.9329928160f, -0.9373390079f, + -0.9415440559f, -0.9456073046f, -0.9495281577f, -0.9533060193f, -0.9569403529f, + -0.9604305029f, -0.9637760520f, -0.9669764638f, -0.9700312614f, -0.9729399681f, + -0.9757021070f, -0.9783173800f, -0.9807852507f, -0.9831054807f, -0.9852776527f, + -0.9873014092f, -0.9891765118f, -0.9909026623f, -0.9924795628f, -0.9939069748f, + -0.9951847196f, -0.9963126183f, -0.9972904325f, -0.9981181026f, -0.9987954497f, + -0.9993223548f, -0.9996988177f, -0.9999247193f, + }}; + +const FLOAT32 iusace_pre_post_twid_cos_sin_64[4][64] = { + { + 0.9999811649f, 0.9995294213f, 0.9984755516f, 0.9968202710f, 0.9945645928f, 0.9917097688f, + 0.9882575870f, 0.9842100739f, 0.9795697927f, 0.9743393660f, 0.9685220718f, 0.9621214271f, + 0.9551411867f, 0.9475855827f, 0.9394592047f, 0.9307669401f, 0.9215140343f, 0.9117060304f, + 0.9013488293f, 0.8904487491f, 0.8790122271f, 0.8670462370f, 0.8545579910f, 0.8415549994f, + 0.8280450702f, 0.8140363097f, 0.7995372415f, 0.7845565677f, 0.7691033483f, 0.7531868219f, + 0.7368165851f, 0.7200025320f, 0.7027547359f, 0.6850836873f, 0.6669999361f, 0.6485143900f, + 0.6296382546f, 0.6103827953f, 0.5907596946f, 0.5707807541f, 0.5504579544f, 0.5298036337f, + 0.5088301301f, 0.4875501692f, 0.4659765065f, 0.4441221356f, 0.4220002592f, 0.3996241987f, + 0.3770074248f, 0.3541635275f, 0.3311063051f, 0.3078496456f, 0.2844075263f, 0.2607941031f, + 0.2370236069f, 0.2131103128f, 0.1890686601f, 0.1649131179f, 0.1406582445f, 0.1163186282f, + 0.0919089541f, 0.0674439222f, 0.0429382585f, 0.0184067301f, + }, + { + -0.0061358847f, -0.0306748040f, -0.0551952459f, -0.0796824396f, -0.1041216329f, + -0.1284981072f, -0.1527971923f, -0.1770042181f, -0.2011046410f, -0.2250839174f, + -0.2489276081f, -0.2726213634f, -0.2961508930f, -0.3195020258f, -0.3426607251f, + -0.3656129837f, -0.3883450329f, -0.4108431637f, -0.4330938160f, -0.4550835788f, + -0.4767992198f, -0.4982276559f, -0.5193560123f, -0.5401714444f, -0.5606615543f, + -0.5808139443f, -0.6006164551f, -0.6200572252f, -0.6391244531f, -0.6578066945f, + -0.6760926843f, -0.6939714551f, -0.7114322186f, -0.7284643650f, -0.7450577617f, + -0.7612023950f, -0.7768884897f, -0.7921065688f, -0.8068475723f, -0.8211025000f, + -0.8348628879f, -0.8481203318f, -0.8608669639f, -0.8730949759f, -0.8847970963f, + -0.8959662318f, -0.9065957069f, -0.9166790843f, -0.9262102246f, -0.9351835251f, + -0.9435934424f, -0.9514350295f, -0.9587034583f, -0.9653944373f, -0.9715039134f, + -0.9770281315f, -0.9819638729f, -0.9863080978f, -0.9900581837f, -0.9932119250f, + -0.9957674146f, -0.9977230430f, -0.9990777373f, -0.9998306036f, + }, + { + 1.0000000000f, 0.9996988177f, 0.9987954497f, 0.9972904325f, 0.9951847196f, 0.9924795628f, + 0.9891765118f, 0.9852776527f, 0.9807852507f, 0.9757021070f, 0.9700312614f, 0.9637760520f, + 0.9569403529f, 0.9495281577f, 0.9415440559f, 0.9329928160f, 0.9238795042f, 0.9142097831f, + 0.9039893150f, 0.8932242990f, 0.8819212914f, 0.8700869679f, 0.8577286005f, 0.8448535800f, + 0.8314695954f, 0.8175848126f, 0.8032075167f, 0.7883464098f, 0.7730104327f, 0.7572088242f, + 0.7409511209f, 0.7242470980f, 0.7071067691f, 0.6895405650f, 0.6715589762f, 0.6531728506f, + 0.6343932748f, 0.6152315736f, 0.5956993103f, 0.5758081675f, 0.5555702448f, 0.5349976420f, + 0.5141027570f, 0.4928981960f, 0.4713967443f, 0.4496113360f, 0.4275550842f, 0.4052413106f, + 0.3826834261f, 0.3598950505f, 0.3368898630f, 0.3136817515f, 0.2902846634f, 0.2667127550f, + 0.2429801822f, 0.2191012353f, 0.1950903237f, 0.1709618866f, 0.1467304677f, 0.1224106774f, + 0.0980171412f, 0.0735645667f, 0.0490676761f, 0.0245412290f, + }, + { + -0.0000000000f, -0.0245412290f, -0.0490676761f, -0.0735645667f, -0.0980171412f, + -0.1224106774f, -0.1467304677f, -0.1709618866f, -0.1950903237f, -0.2191012353f, + -0.2429801822f, -0.2667127550f, -0.2902846634f, -0.3136817515f, -0.3368898630f, + -0.3598950505f, -0.3826834261f, -0.4052413106f, -0.4275550842f, -0.4496113360f, + -0.4713967443f, -0.4928981960f, -0.5141027570f, -0.5349976420f, -0.5555702448f, + -0.5758081675f, -0.5956993103f, -0.6152315736f, -0.6343932748f, -0.6531728506f, + -0.6715589762f, -0.6895405650f, -0.7071067691f, -0.7242470980f, -0.7409511209f, + -0.7572088242f, -0.7730104327f, -0.7883464098f, -0.8032075167f, -0.8175848126f, + -0.8314695954f, -0.8448535800f, -0.8577286005f, -0.8700869679f, -0.8819212914f, + -0.8932242990f, -0.9039893150f, -0.9142097831f, -0.9238795042f, -0.9329928160f, + -0.9415440559f, -0.9495281577f, -0.9569403529f, -0.9637760520f, -0.9700312614f, + -0.9757021070f, -0.9807852507f, -0.9852776527f, -0.9891765118f, -0.9924795628f, + -0.9951847196f, -0.9972904325f, -0.9987954497f, -0.9996988177f, + }}; + +const FLOAT32 iusace_pre_post_twid_cos_sin_32[4][32] = { + { + 0.9999247193f, 0.9981181026f, 0.9939069748f, 0.9873014092f, 0.9783173800f, 0.9669764638f, + 0.9533060193f, 0.9373390079f, 0.9191138744f, 0.8986744881f, 0.8760700822f, 0.8513551950f, + 0.8245893121f, 0.7958369255f, 0.7651672363f, 0.7326542735f, 0.6983762383f, 0.6624158025f, + 0.6248595119f, 0.5857978463f, 0.5453249812f, 0.5035383701f, 0.4605387151f, 0.4164295495f, + 0.3713172078f, 0.3253102899f, 0.2785196900f, 0.2310581058f, 0.1830398887f, 0.1345807016f, + 0.0857973099f, 0.0368072242f, + }, + { + -0.0122715384f, -0.0613207370f, -0.1102222055f, -0.1588581502f, -0.2071113735f, + -0.2548656464f, -0.3020059466f, -0.3484186828f, -0.3939920366f, -0.4386162460f, + -0.4821837842f, -0.5245896578f, -0.5657318234f, -0.6055110693f, -0.6438315511f, + -0.6806010008f, -0.7157308459f, -0.7491363883f, -0.7807372212f, -0.8104571700f, + -0.8382247090f, -0.8639728427f, -0.8876396418f, -0.9091680050f, -0.9285060763f, + -0.9456073046f, -0.9604305029f, -0.9729399681f, -0.9831054807f, -0.9909026623f, + -0.9963126183f, -0.9993223548f, + }, + { + 1.0000000000f, 0.9987954497f, 0.9951847196f, 0.9891765118f, 0.9807852507f, 0.9700312614f, + 0.9569403529f, 0.9415440559f, 0.9238795042f, 0.9039893150f, 0.8819212914f, 0.8577286005f, + 0.8314695954f, 0.8032075167f, 0.7730104327f, 0.7409511209f, 0.7071067691f, 0.6715589762f, + 0.6343932748f, 0.5956993103f, 0.5555702448f, 0.5141027570f, 0.4713967443f, 0.4275550842f, + 0.3826834261f, 0.3368898630f, 0.2902846634f, 0.2429801822f, 0.1950903237f, 0.1467304677f, + 0.0980171412f, 0.0490676761f, + }, + { + -0.0000000000f, -0.0490676761f, -0.0980171412f, -0.1467304677f, -0.1950903237f, + -0.2429801822f, -0.2902846634f, -0.3368898630f, -0.3826834261f, -0.4275550842f, + -0.4713967443f, -0.5141027570f, -0.5555702448f, -0.5956993103f, -0.6343932748f, + -0.6715589762f, -0.7071067691f, -0.7409511209f, -0.7730104327f, -0.8032075167f, + -0.8314695954f, -0.8577286005f, -0.8819212914f, -0.9039893150f, -0.9238795042f, + -0.9415440559f, -0.9569403529f, -0.9700312614f, -0.9807852507f, -0.9891765118f, + -0.9951847196f, -0.9987954497f, + }}; + +const UWORD32 iusace_sampl_freq_idx_table[32] = { + 96000, /* 0x00 */ + 88200, /* 0x01 */ + 64000, /* 0x02 */ + 48000, /* 0x03 */ + 44100, /* 0x04 */ + 32000, /* 0x05 */ + 24000, /* 0x06 */ + 22050, /* 0x07 */ + 16000, /* 0x08 */ + 12000, /* 0x09 */ + 11025, /* 0x0a */ + 8000, /* 0x0b */ + 7350, /* 0x0c */ + -1 /* reserved */, /* 0x0d */ + -1 /* reserved */, /* 0x0e */ + 57600, /* 0x0f */ + 51200, /* 0x10 */ + 40000, /* 0x11 */ + 38400, /* 0x12 */ + 34150, /* 0x13 */ + 28800, /* 0x14 */ + 25600, /* 0x15 */ + 20000, /* 0x16 */ + 19200, /* 0x17 */ + 17075, /* 0x18 */ + 14400, /* 0x19 */ + 12800, /* 0x1a */ + 9600, /* 0x1b */ + -1 /* reserved */, /* 0x1c */ + -1 /* reserved */, /* 0x1d */ + -1 /* reserved */, /* 0x1e */ + 0 /* escape value */, /* 0x1f */ +}; + +const WORD32 iusace_bandwidth_table[8][2] = {{64000, 20000}, {56000, 16000}, {48000, 14000}, + {40000, 12000}, {32000, 20000}, {24000, 6000}, + {12000, 3500}, {-1, 0}}; + +const FLOAT64 iusace_pow_table[9000] = { + 0.000000000000000f, 1.000000000000000f, 2.519842099789746f, + 4.326748710922224f, 6.349604207872797f, 8.549879733383484f, + 10.902723556992836f, 13.390518279406722f, 15.999999999999998f, + 18.720754407467133f, 21.544346900318832f, 24.463780996262468f, + 27.473141821279960f, 30.567350940369842f, 33.741991698453212f, + 36.993181114957046f, 40.317473596635935f, 43.711787041189993f, + 47.173345095760126f, 50.699631325716943f, 54.288352331898118f, + 57.937407704003519f, 61.644865274418500f, 65.408940536585988f, + 69.227979374755591f, 73.100443455321638f, 77.024897778591608f, + 80.999999999999986f, 85.024491212518527f, 89.097187944889555f, + 93.216975178615741f, 97.382800224133163f, 101.593667325964745f, + 105.848632889862245f, 110.146801243434410f, 114.487320856600604f, + 118.869380960206527f, 123.292208510900238f, 127.755065458360576f, + 132.257246277552468f, 136.798075734135722f, 141.376906855691914f, + 145.993119085230859f, 150.646116596629099f, 155.335326754346738f, + 160.060198702052787f, 164.820202066733486f, 169.614825766518607f, + 174.443576911885344f, 179.305979791125566f, 184.201574932019270f, + 189.129918232575619f, 194.090580154496848f, 199.083144973716770f, + 204.107210082969402f, 209.162385341876472f, 214.248292470507522f, + 219.364564482777837f, 224.510845156412131f, 229.686788536522300f, + 234.892058470131758f, 240.126328169232494f, 245.389279800185051f, + 250.680604097472610f, 255.999999999999915f, 261.347174308288686f, + 266.721841361064492f, 272.123722729860447f, 277.552546930379606f, + 283.008049149461897f, 288.489970986598905f, 293.998060209022469f, + 299.532070519474075f, 305.091761335829858f, 310.676897581822061f, + 316.287249488155851f, 321.922592403371766f, 327.582706613855350f, + 333.267377172437421f, 338.976393735070246f, 344.709550405101311f, + 350.466645584700132f, 356.247481833026086f, 362.051865730751388f, + 367.879607750582579f, 373.730522133445106f, 379.604426770020780f, + 385.501143087346065f, 391.420495940199430f, 397.362313507023714f, + 403.326427190144670f, 409.312671520062622f, 415.320884063607991f, + 421.350905335764708f, 427.402578714976187f, 433.475750361761698f, + 439.570269140479297f, 445.685986544082709f, 451.822756621727592f, + 457.980435909091284f, 464.158883361277731f, 470.357960288187257f, + 476.577530292236304f, 482.817459208320429f, 489.077615045917412f, + 495.357867933235809f, 501.658090063316877f, 507.978155642003685f, + 514.317940837696483f, 520.677323732816717f, 527.056184276906038f, + 533.454404241291741f, 539.871867175251282f, 546.308458363615046f, + 552.764064785746086f, 559.238575075841936f, 565.731879484504134f, + 572.243869841523406f, 578.774439519833777f, 585.323483400588430f, + 591.890897839312629f, 598.476580633092567f, 605.080430988760440f, + 611.702349492036433f, 618.342238077591901f, 624.999999999999773f, + 631.675539805537483f, 638.368763304811637f, 645.079577546174846f, + 651.807890789904150f, 658.553612483114989f, 665.316653235383569f, + 672.096924795052246f, 678.894340026194300f, 685.708812886214218f, + 692.540258404062001f, 699.388592659039773f, 706.253732760180583f, + 713.135596826179722f, 720.034103965860368f, 726.949174259154347f, + 733.880728738582093f, 740.828689371215432f, 747.792979041105355f, + 754.773521532161908f, 761.770241511470431f, 768.783064513029558f, + 775.811916921898955f, 782.856725958742459f, 789.917419664754448f, + 796.993926886957979f, 804.086177263862737f, 811.194101211470979f, + 818.317629909622269f, 825.456695288665628f, 832.611230016448644f, + 839.781167485616038f, 846.966441801205519f, 854.166987768535137f, + 861.382740881371433f, 868.613637310369768f, 875.859613891782033f, + 883.120608116419589f, 890.396558118867574f, 897.687402666941807f, + 904.993081151381716f, 912.313533575771885f, 919.648700546687564f, + 926.998523264056189f, 934.362943511728986f, 941.741903648258585f, + 949.135346597874218f, 956.543215841652113f, 963.965455408873481f, + 971.402009868565415f, 978.852824321221760f, 986.317844390695882f, + 993.797016216263501f, 1001.290286444850040f, 1008.797602223418039f, + 1016.318911191510324f, 1023.854161473946419f, 1031.403301673665283f, + 1038.966280864713781f, 1046.543048585375800f, 1054.133554831436641f, + 1061.737750049583838f, 1069.355585130935651f, 1076.987011404697796f, + 1084.631980631944089f, 1092.290444999517376f, 1099.962357114048245f, + 1107.647669996089235f, 1115.346337074360690f, 1123.058312180105986f, + 1130.783549541554066f, 1138.522003778485669f, 1146.273629896900957f, + 1154.038383283787880f, 1161.816219701986029f, 1169.607095285145988f, + 1177.410966532780776f, 1185.227790305407780f, 1193.057523819779817f, + 1200.900124644200105f, 1208.755550693924761f, 1216.623760226644208f, + 1224.504711838047797f, 1232.398364457465732f, 1240.304677343587400f, + 1248.223610080256776f, 1256.155122572339451f, 1264.099175041661965f, + 1272.055728023022766f, 1280.024742360269101f, 1288.006179202444400f, + 1295.999999999999545f, 1304.006166501068037f, 1312.024640747806188f, + 1320.055385072792888f, 1328.098362095490302f, 1336.153534718765059f, + 1344.220866125464681f, 1352.300319775052230f, 1360.391859400296198f, + 1368.495449004014517f, 1376.611052855870867f, 1384.738635489224407f, + 1392.878161698029544f, 1401.029596533785480f, 1409.192905302535337f, + 1417.368053561911893f, 1425.555007118232652f, 1433.753732023637440f, + 1441.964194573274426f, 1450.186361302528212f, 1458.420198984291346f, + 1466.665674626279724f, 1474.922755468387550f, 1483.191408980084134f, + 1491.471602857851622f, 1499.763305022659551f, 1508.066483617479435f, + 1516.381107004837531f, 1524.707143764402872f, 1533.044562690612793f, + 1541.393332790334171f, 1549.753423280558081f, 1558.124803586130383f, + 1566.507443337515042f, 1574.901312368590879f, 1583.306380714479474f, + 1591.722618609406936f, 1600.149996484594112f, 1608.588484966179976f, + 1617.038054873173678f, 1625.498677215435691f, 1633.970323191688749f, + 1642.452964187557654f, 1650.946571773634560f, 1659.451117703575164f, + 1667.966573912218564f, 1676.492912513735291f, 1685.030105799801049f, + 1693.578126237795686f, 1702.136946469026952f, 1710.706539306979494f, + 1719.286877735587723f, 1727.877934907532335f, 1736.479684142559563f, + 1745.092098925824985f, 1753.715152906258254f, 1762.348819894950338f, + 1770.993073863563041f, 1779.647888942759664f, 1788.313239420656373f, + 1796.989099741294694f, 1805.675444503133349f, 1814.372248457562137f, + 1823.079486507432193f, 1831.797133705609440f, 1840.525165253543719f, + 1849.263556499857941f, 1858.012282938956332f, 1866.771320209649275f, + 1875.540644093796573f, 1884.320230514968671f, 1893.110055537124026f, + 1901.910095363304208f, 1910.720326334345373f, 1919.540724927605652f, + 1928.371267755709823f, 1937.211931565308305f, 1946.062693235852521f, + 1954.923529778385955f, 1963.794418334349984f, 1972.675336174403583f, + 1981.566260697259395f, 1990.467169428532998f, 1999.378040019606942f, + 2008.298850246507754f, 2017.229578008798171f, 2026.170201328481880f, + 2035.120698348921223f, 2044.081047333768765f, 2053.051226665912509f, + 2062.031214846430885f, 2071.020990493564568f, 2080.020532341695798f, + 2089.029819240344295f, 2098.048830153171366f, 2107.077544156999465f, + 2116.115940440839040f, 2125.163998304931738f, 2134.221697159799533f, + 2143.289016525309762f, 2152.365936029748354f, 2161.452435408903057f, + 2170.548494505161671f, 2179.654093266614382f, 2188.769211746171095f, + 2197.893830100688774f, 2207.027928590104239f, 2216.171487576583786f, + 2225.324487523675998f, 2234.486908995478188f, 2243.658732655810127f, + 2252.839939267398222f, 2262.030509691070165f, 2271.230424884953663f, + 2280.439665903689729f, 2289.658213897652331f, 2298.886050112176235f, + 2308.123155886792574f, 2317.369512654476694f, 2326.625101940900549f, + 2335.889905363693288f, 2345.163904631713194f, 2354.447081544323282f, + 2363.739417990679158f, 2373.040895949020523f, 2382.351497485973141f, + 2391.671204755855797f, 2400.999999999999091f, 2410.337865546065132f, + 2419.684783807381336f, 2429.040737282274677f, 2438.405708553419117f, + 2447.779680287185784f, 2457.162635233000856f, 2466.554556222711199f, + 2475.955426169956354f, 2485.365228069547356f, 2494.783944996848732f, + 2504.211560107173682f, 2513.648056635178818f, 2523.093417894267532f, + 2532.547627276002459f, 2542.010668249518858f, 2551.482524360947991f, + 2560.963179232844141f, 2570.452616563618449f, 2579.950820126979124f, + 2589.457773771374377f, 2598.973461419445812f, 2608.497867067482275f, + 2618.030974784883711f, 2627.572768713625919f, 2637.123233067735327f, + 2646.682352132764663f, 2656.250110265276817f, 2665.826491892332797f, + 2675.411481510984231f, 2685.005063687772235f, 2694.607223058229465f, + 2704.217944326389443f, 2713.837212264297250f, 2723.465011711527950f, + 2733.101327574709558f, 2742.746144827048283f, 2752.399448507860143f, + 2762.061223722108480f, 2771.731455639941942f, 2781.410129496240643f, + 2791.097230590165509f, 2800.792744284709443f, 2810.496656006258945f, + 2820.208951244152104f, 2829.929615550246581f, 2839.658634538489423f, + 2849.395993884491872f, 2859.141679325106452f, 2868.895676658008597f, + 2878.657971741284655f, 2888.428550493021248f, 2898.207398890897366f, + 2907.994502971783731f, 2917.789848831343988f, 2927.593422623637707f, + 2937.405210560731120f, 2947.225198912307860f, 2957.053374005286514f, + 2966.889722223436820f, 2976.734230007004953f, 2986.586883852339724f, + 2996.447670311519687f, 3006.316575991988884f, 3016.193587556190778f, + 3026.078691721209452f, 3035.971875258410819f, 3045.873124993090187f, + 3055.782427804120744f, 3065.699770623603854f, 3075.625140436528000f, + 3085.558524280424535f, 3095.499909245029812f, 3105.449282471949118f, + 3115.406631154325623f, 3125.371942536508868f, 3135.345203913728710f, + 3145.326402631771543f, 3155.315526086659247f, 3165.312561724329498f, + 3175.317497040322905f, 3185.330319579467414f, 3195.351016935569987f, + 3205.379576751107834f, 3215.415986716925090f, 3225.460234571929050f, + 3235.512308102792758f, 3245.572195143655790f, 3255.639883575830027f, + 3265.715361327509981f, 3275.798616373479490f, 3285.889636734828855f, + 3295.988410478666538f, 3306.094925717839487f, 3316.209170610651654f, + 3326.331133360587955f, 3336.460802216038246f, 3346.598165470023105f, + 3356.743211459926442f, 3366.895928567224928f, 3377.056305217221052f, + 3387.224329878782100f, 3397.399991064076403f, 3407.583277328312761f, + 3417.774177269486245f, 3427.972679528119897f, 3438.178772787012349f, + 3448.392445770987251f, 3458.613687246644531f, 3468.842486022110734f, + 3479.078830946797552f, 3489.322710911155355f, 3499.574114846434441f, + 3509.833031724444481f, 3520.099450557318505f, 3530.373360397275064f, + 3540.654750336388588f, 3550.943609506353368f, 3561.239927078258006f, + 3571.543692262353488f, 3581.854894307830818f, 3592.173522502593642f, + 3602.499566173037238f, 3612.833014683827514f, 3623.173857437681363f, + 3633.522083875150201f, 3643.877683474403057f, 3654.240645751014199f, + 3664.610960257749412f, 3674.988616584356350f, 3685.373604357354452f, + 3695.765913239829388f, 3706.165532931224789f, 3716.572453167139884f, + 3726.986663719126227f, 3737.408154394487610f, 3747.836915036078153f, + 3758.272935522107218f, 3768.716205765941140f, 3779.166715715907685f, + 3789.624455355105511f, 3800.089414701208170f, 3810.561583806276758f, + 3821.040952756569368f, 3831.527511672353285f, 3842.021250707719446f, + 3852.522160050395996f, 3863.030229921567297f, 3873.545450575689301f, + 3884.067812300310834f, 3894.597305415892151f, 3905.133920275628498f, + 3915.677647265273208f, 3926.228476802960358f, 3936.786399339033778f, + 3947.351405355870611f, 3957.923485367713511f, 3968.502629920496929f, + 3979.088829591679769f, 3989.682074990077581f, 4000.282356755694764f, + 4010.889665559561308f, 4021.503992103565452f, 4032.125327120294514f, + 4042.753661372869374f, 4053.388985654785756f, 4064.031290789755076f, + 4074.680567631544818f, 4085.336807063822107f, 4095.999999999998181f, + 4106.670137383071051f, 4117.347210185474978f, 4128.031209408925861f, + 4138.722126084267984f, 4149.419951271326681f, 4160.124676058758268f, + 4170.836291563898158f, 4181.554788932618067f, 4192.280159339176862f, + 4203.012393986074130f, 4213.751484103910116f, 4224.497420951238382f, + 4235.250195814425751f, 4246.009800007509511f, 4256.776224872057355f, + 4267.549461777030956f, 4278.329502118642267f, 4289.116337320219827f, + 4299.909958832071425f, 4310.710358131349494f, 4321.517526721913782f, + 4332.331456134200380f, 4343.152137925088027f, 4353.979563677767146f, + 4364.813725001605235f, 4375.654613532022267f, 4386.502220930358817f, + 4397.356538883746907f, 4408.217559104982683f, 4419.085273332401812f, + 4429.959673329753059f, 4440.840750886072783f, 4451.728497815560331f, + 4462.622905957457078f, 4473.523967175922735f, 4484.431673359912566f, + 4495.346016423058245f, 4506.266988303549624f, 4517.194580964011948f, + 4528.128786391389440f, 4539.069596596827978f, 4550.017003615558679f, + 4560.970999506780572f, 4571.931576353546006f, 4582.898726262646960f, + 4593.872441364500446f, 4604.852713813034825f, 4615.839535785581575f, + 4626.832899482757057f, 4637.832797128358834f, 4648.839220969251073f, + 4659.852163275256316f, 4670.871616339047250f, 4681.897572476039386f, + 4692.930024024283739f, 4703.968963344359508f, 4715.014382819266757f, + 4726.066274854325457f, 4737.124631877068168f, 4748.189446337137269f, + 4759.260710706180362f, 4770.338417477749317f, 4781.422559167199324f, + 4792.513128311585206f, 4803.610117469561374f, 4814.713519221285424f, + 4825.823326168315361f, 4836.939530933509559f, 4848.062126160934895f, + 4859.191104515763072f, 4870.326458684177851f, 4881.468181373276821f, + 4892.616265310976814f, 4903.770703245919321f, 4914.931487947374990f, + 4926.098612205150857f, 4937.272068829496675f, 4948.451850651011227f, + 4959.637950520555023f, 4970.830361309152067f, 4982.029075907904371f, + 4993.234087227897362f, 5004.445388200115303f, 5015.662971775346705f, + 5026.886830924100650f, 5038.116958636513118f, 5049.353347922266039f, + 5060.595991810492706f, 5071.844883349699558f, 5083.100015607673413f, + 5094.361381671399613f, 5105.628974646974712f, 5116.902787659524620f, + 5128.182813853120024f, 5139.469046390691801f, 5150.761478453947348f, + 5162.060103243293270f, 5173.364913977747165f, 5184.675903894859402f, + 5195.993066250632182f, 5207.316394319438587f, 5218.645881393943455f, + 5229.981520785023349f, 5241.323305821684698f, 5252.671229850991949f, + 5264.025286237982982f, 5275.385468365595443f, 5286.751769634587617f, + 5298.124183463463851f, 5309.502703288395423f, 5320.887322563145972f, + 5332.278034758997819f, 5343.674833364675578f, 5355.077711886271572f, + 5366.486663847172167f, 5377.901682787985010f, 5389.322762266463542f, + 5400.749895857436968f, 5412.183077152735677f, 5423.622299761123031f, + 5435.067557308218966f, 5446.518843436431780f, 5457.976151804887195f, + 5469.439476089359232f, 5480.908809982197454f, 5492.384147192260571f, + 5503.865481444845500f, 5515.352806481620064f, 5526.846116060552049f, + 5538.345403955846450f, 5549.850663957873621f, 5561.361889873102882f, + 5572.879075524036125f, 5584.402214749145060f, 5595.931301402797544f, + 5607.466329355201196f, 5619.007292492329725f, 5630.554184715865631f, + 5642.106999943128358f, 5653.665732107016993f, 5665.230375155942966f, + 5676.800923053765473f, 5688.377369779733272f, 5699.959709328416466f, + 5711.547935709647390f, 5723.142042948458766f, 5734.742025085020941f, + 5746.347876174580961f, 5757.959590287401625f, 5769.577161508700556f, + 5781.200583938591080f, 5792.829851692021293f, 5804.464958898714940f, + 5816.105899703111390f, 5827.752668264306521f, 5839.405258755997238f, + 5851.063665366419627f, 5862.727882298290751f, 5874.397903768754077f, + 5886.073724009320358f, 5897.755337265809430f, 5909.442737798295639f, + 5921.135919881050540f, 5932.834877802487426f, 5944.539605865103113f, + 5956.250098385426099f, 5967.966349693957454f, 5979.688354135120790f, + 5991.416106067202236f, 6003.149599862300420f, 6014.888829906270075f, + 6026.633790598667474f, 6038.384476352703132f, 6050.140881595178143f, + 6061.903000766441437f, 6073.670828320331566f, 6085.444358724126687f, + 6097.223586458489081f, 6109.008506017419677f, 6120.799111908199848f, + 6132.595398651345022f, 6144.397360780551935f, 6156.204992842645879f, + 6168.018289397536137f, 6179.837245018157773f, 6191.661854290430711f, + 6203.492111813202428f, 6215.328012198201577f, 6227.169550069992511f, + 6239.016720065918889f, 6250.869516836062758f, 6262.727935043189063f, + 6274.591969362705640f, 6286.461614482606819f, 6298.336865103432501f, + 6310.217715938217225f, 6322.104161712445602f, 6333.996197164003206f, + 6345.893817043131094f, 6357.797016112378515f, 6369.705789146558345f, + 6381.620130932701613f, 6393.540036270007477f, 6405.465499969803204f, + 6417.396516855497794f, 6429.333081762532856f, 6441.275189538345330f, + 6453.222835042313818f, 6465.176013145724028f, 6477.134718731716021f, + 6489.098946695246923f, 6501.068691943044541f, 6513.043949393562798f, + 6525.024713976941712f, 6537.010980634961015f, 6549.002744321001046f, + 6560.999999999996362f, 6573.002742648398453f, 6585.010967254128445f, + 6597.024668816537087f, 6609.043842346365636f, 6621.068482865700389f, + 6633.098585407935389f, 6645.134145017726951f, 6657.175156750957285f, + 6669.221615674689929f, 6681.273516867134276f, 6693.330855417600105f, + 6705.393626426459377f, 6717.461825005108039f, 6729.535446275926006f, + 6741.614485372233503f, 6753.698937438260145f, 6765.788797629096734f, + 6777.884061110663424f, 6789.984723059666067f, 6802.090778663562560f, + 6814.202223120520102f, 6826.319051639379722f, 6838.441259439618079f, + 6850.568841751307446f, 6862.701793815082965f, 6874.840110882098998f, + 6886.983788213999105f, 6899.132821082872397f, 6911.287204771220786f, + 6923.446934571919883f, 6935.612005788186252f, 6947.782413733536487f, + 6959.958153731753555f, 6972.139221116853150f, 6984.325611233040945f, + 6996.517319434686215f, 7008.714341086277273f, 7020.916671562394185f, + 7033.124306247667846f, 7045.337240536748141f, 7057.555469834268479f, + 7069.778989554810323f, 7082.007795122871357f, 7094.241881972827287f, + 7106.481245548901825f, 7118.725881305128496f, 7130.975784705322440f, + 7143.230951223039483f, 7155.491376341551586f, 7167.757055553803184f, + 7180.027984362389361f, 7192.304158279513103f, 7204.585572826957105f, + 7216.872223536051933f, 7229.164105947640564f, 7241.461215612049273f, + 7253.763548089050346f, 7266.071098947837527f, 7278.383863766986906f, + 7290.701838134429636f, 7303.025017647417371f, 7315.353397912493165f, + 7327.686974545459634f, 7340.025743171346221f, 7352.369699424380087f, + 7364.718838947954282f, 7377.073157394596819f, 7389.432650425941574f, + 7401.797313712693722f, 7414.167142934606090f, 7426.542133780442782f, + 7438.922281947950978f, 7451.307583143834563f, 7463.698033083717746f, + 7476.093627492121414f, 7488.494362102430387f, 7500.900232656865228f, + 7513.311234906452228f, 7525.727364610994300f, 7538.148617539044608f, + 7550.574989467872911f, 7563.006476183441919f, 7575.443073480373641f, + 7587.884777161924831f, 7600.331583039959696f, 7612.783486934915345f, + 7625.240484675779953f, 7637.702572100063662f, 7650.169745053767656f, + 7662.641999391359604f, 7675.119330975744560f, 7687.601735678240402f, + 7700.089209378544183f, 7712.581747964711212f, 7725.079347333125042f, + 7737.582003388472913f, 7750.089712043713917f, 7762.602469220058083f, + 7775.120270846935455f, 7787.643112861973350f, 7800.170991210964530f, + 7812.703901847848101f, 7825.241840734676771f, 7837.784803841596840f, + 7850.332787146815463f, 7862.885786636580633f, 7875.443798305153905f, + 7888.006818154784014f, 7900.574842195680503f, 7913.147866445990076f, + 7925.725886931772038f, 7938.308899686971927f, 7950.896900753395130f, + 7963.489886180685062f, 7976.087852026295877f, 7988.690794355468825f, + 8001.298709241208599f, 8013.911592764256966f, 8026.529441013069118f, + 8039.152250083789113f, 8051.780016080227142f, 8064.412735113834970f, + 8077.050403303679559f, 8089.693016776422155f, 8102.340571666294636f, + 8114.993064115073139f, 8127.650490272057141f, 8140.312846294044903f, + 8152.980128345309822f, 8165.652332597578607f, 8178.329455230004896f, + 8191.011492429152895f, 8203.698440388965537f, 8216.390295310746296f, + 8229.087053403141908f, 8241.788710882106898f, 8254.495263970893575f, + 8267.206708900021113f, 8279.923041907257357f, 8292.644259237595179f, + 8305.370357143230649f, 8318.101331883543025f, 8330.837179725065653f, + 8343.577896941475046f, 8356.323479813558151f, 8369.073924629197791f, + 8381.829227683350837f, 8394.589385278020927f, 8407.354393722242094f, + 8420.124249332058753f, 8432.898948430494784f, 8445.678487347549890f, + 8458.462862420157762f, 8471.252069992180623f, 8484.046106414383758f, + 8496.844968044408233f, 8509.648651246763620f, 8522.457152392795251f, + 8535.270467860666031f, 8548.088594035343704f, 8560.911527308566292f, + 8573.739264078840279f, 8586.571800751400588f, 8599.409133738206947f, + 8612.251259457914784f, 8625.098174335855219f, 8637.949874804020510f, + 8650.806357301038588f, 8663.667618272156687f, 8676.533654169224974f, + 8689.404461450663803f, 8702.280036581460081f, 8715.160376033141802f, + 8728.045476283750759f, 8740.935333817838909f, 8753.829945126435632f, + 8766.729306707033174f, 8779.633415063572102f, 8792.542266706415830f, + 8805.455858152332439f, 8818.374185924481935f, 8831.297246552390789f, + 8844.225036571935561f, 8857.157552525326537f, 8870.094790961084072f, + 8883.036748434029505f, 8895.983421505252409f, 8908.934806742106957f, + 8921.890900718184639f, 8934.851700013299705f, 8947.817201213470980f, + 8960.787400910900033f, 8973.762295703960262f, 8986.741882197173254f, + 8999.726157001192405f, 9012.715116732788374f, 9025.708758014823616f, + 9038.707077476246923f, 9051.710071752064323f, 9064.717737483328165f, + 9077.730071317115289f, 9090.747069906517936f, 9103.768729910614638f, + 9116.795047994464767f, 9129.826020829081244f, 9142.861645091423270f, + 9155.901917464372673f, 9168.946834636715721f, 9181.996393303135847f, + 9195.050590164184541f, 9208.109421926274081f, 9221.172885301655697f, + 9234.240977008405025f, 9247.313693770407554f, 9260.391032317338613f, + 9273.472989384647008f, 9286.559561713542280f, 9299.650746050974703f, + 9312.746539149620730f, 9325.846937767868440f, 9338.951938669801166f, + 9352.061538625175672f, 9365.175734409413053f, 9378.294522803584186f, + 9391.417900594384264f, 9404.545864574127336f, 9417.678411540726302f, + 9430.815538297674721f, 9443.957241654035897f, 9457.103518424426511f, + 9470.254365429000245f, 9483.409779493429596f, 9496.569757448893142f, + 9509.734296132066447f, 9522.903392385091138f, 9536.077043055580361f, + 9549.255244996582405f, 9562.437995066582516f, 9575.625290129479254f, + 9588.817127054573575f, 9602.013502716548828f, 9615.214413995463474f, + 9628.419857776725621f, 9641.629830951093027f, 9654.844330414643991f, + 9668.063353068771903f, 9681.286895820167047f, 9694.514955580800233f, + 9707.747529267919163f, 9720.984613804015680f, 9734.226206116827598f, + 9747.472303139318683f, 9760.722901809664108f, 9773.977999071232261f, + 9787.237591872581106f, 9800.501677167432717f, 9813.770251914669643f, + 9827.043313078309438f, 9840.320857627502846f, 9853.602882536511970f, + 9866.889384784699359f, 9880.180361356511639f, 9893.475809241468596f, + 9906.775725434152264f, 9920.080106934185096f, 9933.388950746224509f, + 9946.702253879942873f, 9960.020013350022055f, 9973.342226176129770f, + 9986.668889382915950f, 9999.999999999994543f, 10013.335555061928972f, + 10026.675551608221213f, 10040.019986683300885f, 10053.368857336508881f, + 10066.722160622080992f, 10080.079893599144270f, 10093.442053331697025f, + 10106.808636888597903f, 10120.179641343549520f, 10133.555063775094823f, + 10146.934901266595261f, 10160.319150906219875f, 10173.707809786936195f, + 10187.100875006495698f, 10200.498343667417430f, 10213.900212876984369f, + 10227.306479747221601f, 10240.717141394889040f, 10254.132194941466878f, + 10267.551637513146488f, 10280.975466240814058f, 10294.403678260039669f, + 10307.836270711066391f, 10321.273240738795721f, 10334.714585492780316f, + 10348.160302127203977f, 10361.610387800878016f, 10375.064839677221244f, + 10388.523654924258153f, 10401.986830714593452f, 10415.454364225412064f, + 10428.926252638464575f, 10442.402493140049046f, 10455.883082921007372f, + 10469.368019176708913f, 10482.857299107039580f, 10496.350919916392741f, + 10509.848878813652846f, 10523.351173012188156f, 10536.857799729838007f, + 10550.368756188900079f, 10563.884039616121299f, 10577.403647242685111f, + 10590.927576304196918f, 10604.455824040678635f, 10617.988387696555947f, + 10631.525264520641940f, 10645.066451766135287f, 10658.611946690598415f, + 10672.161746555955688f, 10685.715848628475214f, 10699.274250178761577f, + 10712.836948481746731f, 10726.403940816675458f, 10739.975224467090811f, + 10753.550796720834114f, 10767.130654870026774f, 10780.714796211057546f, + 10794.303218044578898f, 10807.895917675486999f, 10821.492892412921719f, + 10835.094139570248444f, 10848.699656465047156f, 10862.309440419108796f, + 10875.923488758415260f, 10889.541798813137575f, 10903.164367917619529f, + 10916.791193410372216f, 10930.422272634055844f, 10944.057602935479736f, + 10957.697181665582320f, 10971.341006179427495f, 10984.989073836190073f, + 10998.641381999148507f, 11012.297928035675795f, 11025.958709317223111f, + 11039.623723219316162f, 11053.292967121540642f, 11066.966438407538590f, + 11080.644134464990202f, 11094.326052685608374f, 11108.012190465127787f, + 11121.702545203295813f, 11135.397114303863418f, 11149.095895174570614f, + 11162.798885227142819f, 11176.506081877278120f, 11190.217482544634549f, + 11203.933084652828256f, 11217.652885629415323f, 11231.376882905886305f, + 11245.105073917658956f, 11258.837456104061857f, 11272.574026908332598f, + 11286.314783777601406f, 11300.059724162887505f, 11313.808845519082752f, + 11327.562145304951628f, 11341.319620983111236f, 11355.081270020033116f, + 11368.847089886023241f, 11382.617078055218371f, 11396.391232005578786f, + 11410.169549218873726f, 11423.952027180675941f, 11437.738663380348953f, + 11451.529455311041602f, 11465.324400469678949f, 11479.123496356951364f, + 11492.926740477303611f, 11506.734130338931209f, 11520.545663453764064f, + 11534.361337337466466f, 11548.181149509422539f, 11562.005097492723507f, + 11575.833178814169514f, 11589.665391004253252f, 11603.501731597149046f, + 11617.342198130714678f, 11631.186788146467734f, 11645.035499189589245f, + 11658.888328808910956f, 11672.745274556904405f, 11686.606333989675477f, + 11700.471504666955298f, 11714.340784152085689f, 11728.214170012020986f, + 11742.091659817311665f, 11755.973251142100708f, 11769.858941564110864f, + 11783.748728664635564f, 11797.642610028538911f, 11811.540583244237496f, + 11825.442645903696757f, 11839.348795602420068f, 11853.259029939445099f, + 11867.173346517332902f, 11881.091742942155179f, 11895.014216823492461f, + 11908.940765774426836f, 11922.871387411525575f, 11936.806079354839312f, + 11950.744839227896591f, 11964.687664657683854f, 11978.634553274652717f, + 11992.585502712699963f, 12006.540510609167541f, 12020.499574604828013f, + 12034.462692343879098f, 12048.429861473938217f, 12062.401079646031576f, + 12076.376344514588709f, 12090.355653737431567f, 12104.339004975769058f, + 12118.326395894187954f, 12132.317824160643795f, 12146.313287446457252f, + 12160.312783426303213f, 12174.316309778205323f, 12188.323864183525075f, + 12202.335444326954530f, 12216.351047896510863f, 12230.370672583530904f, + 12244.394316082656587f, 12258.421976091831311f, 12272.453650312296304f, + 12286.489336448574250f, 12300.529032208471108f, 12314.572735303057925f, + 12328.620443446678109f, 12342.672154356921965f, 12356.727865754637605f, + 12370.787575363909127f, 12384.851280912054790f, 12398.918980129623378f, + 12412.990670750381469f, 12427.066350511306155f, 12441.146017152581408f, + 12455.229668417588982f, 12469.317302052901141f, 12483.408915808269740f, + 12497.504507436629865f, 12511.604074694078008f, 12525.707615339877520f, + 12539.815127136444062f, 12553.926607849341963f, 12568.042055247275130f, + 12582.161467102081588f, 12596.284841188726205f, 12610.412175285289777f, + 12624.543467172970850f, 12638.678714636069344f, 12652.817915461984740f, + 12666.961067441208797f, 12681.108168367316466f, 12695.259216036962243f, + 12709.414208249869262f, 12723.573142808827470f, 12737.736017519680900f, + 12751.902830191325847f, 12766.073578635703598f, 12780.248260667787690f, + 12794.426874105587558f, 12808.609416770132157f, 12822.795886485468145f, + 12836.986281078652610f, 12851.180598379743969f, 12865.378836221801976f, + 12879.580992440871341f, 12893.787064875983560f, 12907.997051369144174f, + 12922.210949765334590f, 12936.428757912495712f, 12950.650473661524302f, + 12964.876094866272979f, 12979.105619383533849f, 12993.339045073038506f, + 13007.576369797454390f, 13021.817591422368423f, 13036.062707816285183f, + 13050.311716850628727f, 13064.564616399722581f, 13078.821404340791560f, + 13093.082078553954489f, 13107.346636922216931f, 13121.615077331465727f, + 13135.887397670458085f, 13150.163595830827035f, 13164.443669707059598f, + 13178.727617196502251f, 13193.015436199351825f, 13207.307124618648231f, + 13221.602680360265367f, 13235.902101332911116f, 13250.205385448118250f, + 13264.512530620238977f, 13278.823534766434022f, 13293.138395806676272f, + 13307.457111663734395f, 13321.779680263176488f, 13336.106099533355518f, + 13350.436367405409328f, 13364.770481813249717f, 13379.108440693562443f, + 13393.450241985796310f, 13407.795883632157711f, 13422.145363577606986f, + 13436.498679769854789f, 13450.855830159345714f, 13465.216812699265574f, + 13479.581625345528664f, 13493.950266056772307f, 13508.322732794349577f, + 13522.699023522329298f, 13537.079136207483316f, 13551.463068819286491f, + 13565.850819329905789f, 13580.242385714200282f, 13594.637765949710229f, + 13609.036958016657081f, 13623.439959897927110f, 13637.846769579080501f, + 13652.257385048333163f, 13666.671804296560367f, 13681.090025317284017f, + 13695.512046106669004f, 13709.937864663521395f, 13724.367478989277515f, + 13738.800887088003947f, 13753.238086966384799f, 13767.679076633727163f, + 13782.123854101939287f, 13796.572417385545123f, 13811.024764501658865f, + 13825.480893469997682f, 13839.940802312859887f, 13854.404489055134036f, + 13868.871951724282553f, 13883.343188350341734f, 13897.818196965914467f, + 13912.296975606168417f, 13926.779522308825108f, 13941.265835114159927f, + 13955.755912064991207f, 13970.249751206682049f, 13984.747350587125766f, + 13999.248708256751343f, 14013.753822268510703f, 14028.262690677873252f, + 14042.775311542827694f, 14057.291682923867484f, 14071.811802883994460f, + 14086.335669488704298f, 14100.863280805993782f, 14115.394634906340798f, + 14129.929729862709792f, 14144.468563750548128f, 14159.011134647769723f, + 14173.557440634760496f, 14188.107479794369283f, 14202.661250211900551f, + 14217.218749975118044f, 14231.779977174226588f, 14246.344929901879368f, + 14260.913606253163380f, 14275.486004325601243f, 14290.062122219145749f, + 14304.641958036170763f, 14319.225509881465769f, 14333.812775862235867f, + 14348.403754088098140f, 14362.998442671067096f, 14377.596839725560130f, + 14392.198943368388427f, 14406.804751718747866f, 14421.414262898222660f, + 14436.027475030774440f, 14450.644386242740438f, 14465.264994662828030f, + 14479.889298422105639f, 14494.517295654004556f, 14509.148984494313481f, + 14523.784363081165793f, 14538.423429555048642f, 14553.066182058781123f, + 14567.712618737527009f, 14582.362737738776559f, 14597.016537212348339f, + 14611.674015310381947f, 14626.335170187339827f, 14640.999999999992724f, + 14655.668502907417860f, 14670.340677071002574f, 14685.016520654426131f, + 14699.696031823670637f, 14714.379208746999211f, 14729.066049594966898f, + 14743.756552540407938f, 14758.450715758430306f, 14773.148537426417533f, + 14787.850015724017794f, 14802.555148833142084f, 14817.263934937960585f, + 14831.976372224897204f, 14846.692458882624123f, 14861.412193102059973f, + 14876.135573076362562f, 14890.862597000923415f, 14905.593263073371418f, + 14920.327569493558258f, 14935.065514463556610f, 14949.807096187661955f, + 14964.552312872381663f, 14979.301162726431357f, 14994.053643960734917f, + 15008.809754788413557f, 15023.569493424787652f, 15038.332858087369459f, + 15053.099846995857661f, 15067.870458372133726f, 15082.644690440263730f, + 15097.422541426483804f, 15112.204009559201950f, 15126.989093068994407f, + 15141.777790188596555f, 15156.570099152904731f, 15171.366018198967140f, + 15186.165545565985667f, 15200.968679495301330f, 15215.775418230401556f, + 15230.585760016909262f, 15245.399703102579224f, 15260.217245737298072f, + 15275.038386173073377f, 15289.863122664035473f, 15304.691453466431994f, + 15319.523376838620607f, 15334.358891041069000f, 15349.197994336345801f, + 15364.040684989127840f, 15378.886961266176513f, 15393.736821436355967f, + 15408.590263770609454f, 15423.447286541972062f, 15438.307888025554348f, + 15453.172066498542335f, 15468.039820240195695f, 15482.911147531840470f, + 15497.786046656869075f, 15512.664515900733022f, 15527.546553550939279f, + 15542.432157897044817f, 15557.321327230660245f, 15572.214059845435258f, + 15587.110354037064099f, 15602.010208103272817f, 15616.913620343822913f, + 15631.820589060505881f, 15646.731112557135930f, 15661.645189139546346f, + 15676.562817115593134f, 15691.483994795138642f, 15706.408720490062478f, + 15721.336992514241501f, 15736.268809183560734f, 15751.204168815900630f, + 15766.143069731135256f, 15781.085510251132291f, 15796.031488699740294f, + 15810.981003402797796f, 15825.934052688118754f, 15840.890634885488907f, + 15855.850748326673056f, 15870.814391345400509f, 15885.781562277361445f, + 15900.752259460214191f, 15915.726481233565210f, 15930.704225938983654f, + 15945.685491919977721f, 15960.670277522009201f, 15975.658581092480745f, + 15990.650400980730410f, 16005.645735538035296f, 16020.644583117598813f, + 16035.646942074556137f, 16050.652810765966933f, 16065.662187550806266f, + 16080.675070789973688f, 16095.691458846273235f, 16110.711350084424339f, + 16125.734742871052731f, 16140.761635574684988f, 16155.792026565746710f, + 16170.825914216560705f, 16185.863296901337890f, 16200.904172996182751f, + 16215.948540879078791f, 16230.996398929899442f, 16246.047745530386237f, + 16261.102579064163365f, 16276.160897916721296f, 16291.222700475420424f, + 16306.287985129483786f, 16321.356750269995246f, 16336.428994289895854f, + 16351.504715583982033f, 16366.583912548900116f, 16381.666583583140891f, + 16396.752727087041421f, 16411.842341462775948f, 16426.935425114363170f, + 16442.031976447644411f, 16457.131993870298174f, 16472.235475791829231f, + 16487.342420623561338f, 16502.452826778640883f, 16517.566692672033241f, + 16532.684016720515501f, 16547.804797342676466f, 16562.929032958902098f, + 16578.056721991393715f, 16593.187862864149793f, 16608.322454002962331f, + 16623.460493835416855f, 16638.601980790896050f, 16653.746913300557935f, + 16668.895289797354053f, 16684.047108716014918f, 16699.202368493046379f, + 16714.361067566725978f, 16729.523204377106595f, 16744.688777366009163f, + 16759.857784977011761f, 16775.030225655464164f, 16790.206097848466015f, + 16805.385400004874100f, 16820.568130575302348f, 16835.754288012103643f, + 16850.943870769380737f, 16866.136877302982612f, 16881.333306070493563f, + 16896.533155531229568f, 16911.736424146249192f, 16926.943110378331767f, + 16942.153212691991939f, 16957.366729553454206f, 16972.583659430682019f, + 16987.804000793337764f, 17003.027752112815506f, 17018.254911862204608f, + 17033.485478516311559f, 17048.719450551645423f, 17063.956826446421474f, + 17079.197604680546647f, 17094.441783735630452f, 17109.689362094966782f, + 17124.940338243552105f, 17140.194710668063635f, 17155.452477856852056f, + 17170.713638299966988f, 17185.978190489127883f, 17201.246132917724026f, + 17216.517464080825448f, 17231.792182475164736f, 17247.070286599140672f, + 17262.351774952825508f, 17277.636646037935861f, 17292.924898357854545f, + 17308.216530417623289f, 17323.511540723920916f, 17338.809927785088803f, + 17354.111690111105418f, 17369.416826213593595f, 17384.725334605820535f, + 17400.037213802683254f, 17415.352462320715858f, 17430.671078678089543f, + 17445.993061394587130f, 17461.318408991635806f, 17476.647119992274384f, + 17491.979192921167851f, 17507.314626304585545f, 17522.653418670422980f, + 17537.995568548187293f, 17553.341074468986335f, 17568.689934965535940f, + 17584.042148572156293f, 17599.397713824768289f, 17614.756629260889895f, + 17630.118893419625238f, 17645.484504841682792f, 17660.853462069353554f, + 17676.225763646511041f, 17691.601408118618565f, 17706.980394032718323f, + 17722.362719937424117f, 17737.748384382935910f, 17753.137385921014356f, + 17768.529723104998993f, 17783.925394489790051f, 17799.324398631855729f, + 17814.726734089224919f, 17830.132399421479931f, 17845.541393189767405f, + 17860.953713956780120f, 17876.369360286771553f, 17891.788330745530402f, + 17907.210623900395149f, 17922.636238320254051f, 17938.065172575526958f, + 17953.497425238176220f, 17968.932994881692139f, 17984.371880081103882f, + 17999.814079412972205f, 18015.259591455371265f, 18030.708414787914080f, + 18046.160547991730709f, 18061.615989649464609f, 18077.074738345283549f, + 18092.536792664861423f, 18108.002151195392798f, 18123.470812525571091f, + 18138.942775245599478f, 18154.418037947190896f, 18169.896599223546218f, + 18185.378457669379713f, 18200.863611880886310f, 18216.352060455767059f, + 18231.843801993203670f, 18247.338835093873058f, 18262.837158359936439f, + 18278.338770395032043f, 18293.843669804289675f, 18309.351855194308882f, + 18324.863325173166231f, 18340.378078350411670f, 18355.896113337068527f, + 18371.417428745622601f, 18386.942023190033069f, 18402.469895285717939f, + 18418.001043649550411f, 18433.535466899869789f, 18449.073163656474208f, + 18464.614132540602441f, 18480.158372174955730f, 18495.705881183675956f, + 18511.256658192356554f, 18526.810701828035235f, 18542.368010719183076f, + 18557.928583495715429f, 18573.492418788984651f, 18589.059515231772821f, + 18604.629871458302659f, 18620.203486104212061f, 18635.780357806579559f, + 18651.360485203898861f, 18666.943866936086124f, 18682.530501644479955f, + 18698.120387971841410f, 18713.713524562332168f, 18729.309910061539995f, + 18744.909543116456916f, 18760.512422375479218f, 18776.118546488418360f, + 18791.727914106479147f, 18807.340523882274283f, 18822.956374469809816f, + 18838.575464524488780f, 18854.197792703111190f, 18869.823357663863135f, + 18885.452158066327684f, 18901.084192571470339f, 18916.719459841639036f, + 18932.357958540564141f, 18947.999687333362090f, 18963.644644886520837f, + 18979.292829867907130f, 18994.944240946759237f, 19010.598876793686941f, + 19026.256736080667906f, 19041.917817481047678f, 19057.582119669532403f, + 19073.249641322199750f, 19088.920381116473436f, 19104.594337731145060f, + 19120.271509846355912f, 19135.951896143604245f, 19151.635495305738004f, + 19167.322306016947550f, 19183.012326962783845f, 19198.705556830122077f, + 19214.401994307198038f, 19230.101638083579019f, 19245.804486850167450f, + 19261.510539299208176f, 19277.219794124273903f, 19292.932250020265201f, + 19308.647905683421413f, 19324.366759811302472f, 19340.088811102792533f, + 19355.814058258099976f, 19371.542499978753767f, 19387.274134967599821f, + 19403.008961928797362f, 19418.746979567822564f, 19434.488186591468548f, + 19450.232581707827194f, 19465.980163626303693f, 19481.730931057612906f, + 19497.484882713761181f, 19513.242017308068171f, 19529.002333555141377f, + 19544.765830170897971f, 19560.532505872539332f, 19576.302359378565598f, + 19592.075389408761112f, 19607.851594684208976f, 19623.630973927269224f, + 19639.413525861589733f, 19655.199249212102586f, 19670.988142705016799f, + 19686.780205067825591f, 19702.575435029288201f, 19718.373831319448072f, + 19734.175392669614666f, 19749.980117812370736f, 19765.788005481568689f, + 19781.599054412323312f, 19797.413263341008133f, 19813.230631005273608f, + 19829.051156144014385f, 19844.874837497394765f, 19860.701673806826875f, + 19876.531663814985222f, 19892.364806265788502f, 19908.201099904406874f, + 19924.040543477258325f, 19939.883135732012306f, 19955.728875417578820f, + 19971.577761284104781f, 19987.429792082984932f, 20003.284966566847288f, + 20019.143283489560417f, 20035.004741606218886f, 20050.869339673161448f, + 20066.737076447941945f, 20082.607950689362042f, 20098.481961157427577f, + 20114.359106613384938f, 20130.239385819699237f, 20146.122797540054307f, + 20162.009340539352706f, 20177.899013583715714f, 20193.791815440476057f, + 20209.687744878181547f, 20225.586800666591444f, 20241.488981576669175f, + 20257.394286380596895f, 20273.302713851753651f, 20289.214262764715386f, + 20305.128931895276764f, 20321.046720020414796f, 20336.967625918317935f, + 20352.891648368360620f, 20368.818786151114182f, 20384.749038048346847f, + 20400.682402843009186f, 20416.618879319248663f, 20432.558466262391448f, + 20448.501162458953331f, 20464.446966696628806f, 20480.395877764301986f, + 20496.347894452024775f, 20512.303015551031422f, 20528.261239853734878f, + 20544.222566153719526f, 20560.186993245741178f, 20576.154519925719796f, + 20592.125144990757690f, 20608.098867239106767f, 20624.075685470197641f, + 20640.055598484617803f, 20656.038605084115261f, 20672.024704071594897f, + 20688.013894251125748f, 20704.006174427926453f, 20720.001543408372527f, + 20735.999999999989086f, 20752.001543011454487f, 20768.006171252596687f, + 20784.013883534382330f, 20800.024678668931301f, 20816.038555469505809f, + 20832.055512750506750f, 20848.075549327473709f, 20864.098664017084957f, + 20880.124855637161090f, 20896.154123006646842f, 20912.186464945625630f, + 20928.221880275312287f, 20944.260367818049417f, 20960.301926397311036f, + 20976.346554837684380f, 20992.394251964895375f, 21008.445016605786805f, + 21024.498847588318313f, 21040.555743741573679f, 21056.615703895753541f, + 21072.678726882168121f, 21088.744811533251777f, 21104.813956682537537f, + 21120.886161164682562f, 21136.961423815439048f, 21153.039743471683323f, + 21169.121118971379474f, 21185.205549153604807f, 21201.293032858535298f, + 21217.383568927452870f, 21233.477156202730839f, 21249.573793527841190f, + 21265.673479747358215f, 21281.776213706936687f, 21297.881994253333687f, + 21313.990820234397688f, 21330.102690499054006f, 21346.217603897330264f, + 21362.335559280327288f, 21378.456555500240938f, 21394.580591410333000f, + 21410.707665864963928f, 21426.837777719556470f, 21442.970925830628403f, + 21459.107109055756155f, 21475.246326253603911f, 21491.388576283894508f, + 21507.533858007431263f, 21523.682170286087057f, 21539.833511982797063f, + 21555.987881961566018f, 21572.145279087460949f, 21588.305702226614812f, + 21604.469150246215577f, 21620.635622014520777f, 21636.805116400832048f, + 21652.977632275520591f, 21669.153168510008982f, 21685.331723976763897f, + 21701.513297549317940f, 21717.697888102244178f, 21733.885494511167053f, + 21750.076115652758745f, 21766.269750404735532f, 21782.466397645861434f, + 21798.666056255933654f, 21814.868725115800771f, 21831.074403107344551f, + 21847.283089113483584f, 21863.494782018176920f, 21879.709480706416798f, + 21895.927184064228641f, 21912.147890978667419f, 21928.371600337817654f, + 21944.598311030797049f, 21960.828021947745583f, 21977.060731979829143f, + 21993.296440019243164f, 22009.535144959198078f, 22025.776845693930227f, + 22042.021541118690948f, 22058.269230129757489f, 22074.519911624411179f, + 22090.773584500959259f, 22107.030247658716689f, 22123.289899998013425f, + 22139.552540420187142f, 22155.818167827586876f, 22172.086781123569381f, + 22188.358379212495493f, 22204.632960999730130f, 22220.910525391638657f, + 22237.191071295601432f, 22253.474597619981068f, 22269.761103274147899f, + 22286.050587168469065f, 22302.343048214312148f, 22318.638485324026988f, + 22334.936897410967504f, 22351.238283389469871f, 22367.542642174870707f, + 22383.849972683481610f, 22400.160273832618259f, 22416.473544540567673f, + 22432.789783726602764f, 22449.108990310985973f, 22465.431163214958360f, + 22481.756301360739599f, 22498.084403671527980f, 22514.415469071496773f, + 22530.749496485801501f, 22547.086484840561752f, 22563.426433062879369f, + 22579.769340080823895f, 22596.115204823436216f, 22612.464026220721280f, + 22628.815803203655378f, 22645.170534704178863f, 22661.528219655199791f, + 22677.888856990586646f, 22694.252445645168336f, 22710.618984554734197f, + 22726.988472656033991f, 22743.360908886777906f, 22759.736292185622005f, + 22776.114621492186416f, 22792.495895747044415f, 22808.880113891718793f, + 22825.267274868678214f, 22841.657377621348132f, 22858.050421094096237f, + 22874.446404232243367f, 22890.845325982052600f, 22907.247185290721973f, + 22923.651981106406311f, 22940.059712378195400f, 22956.470378056113987f, + 22972.883977091129054f, 22989.300508435149823f, 23005.719971041016834f, + 23022.142363862498314f, 23038.567685854304727f, 23054.995935972077859f, + 23071.427113172387180f, 23087.861216412729846f, 23104.298244651530695f, + 23120.738196848145890f, 23137.181071962848364f, 23153.626868956846010f, + 23170.075586792263493f, 23186.527224432142248f, 23202.981780840447755f, + 23219.439254982065904f, 23235.899645822795719f, 23252.362952329356631f, + 23268.829173469377565f, 23285.298308211407857f, 23301.770355524899060f, + 23318.245314380223135f, 23334.723183748657902f, 23351.203962602387037f, + 23367.687649914503709f, 23384.174244659006945f, 23400.663745810797991f, + 23417.156152345680312f, 23433.651463240366866f, 23450.149677472461917f, + 23466.650794020471949f, 23483.154811863805662f, 23499.661729982763063f, + 23516.171547358539101f, 23532.684262973230943f, 23549.199875809823425f, + 23565.718384852185409f, 23582.239789085091616f, 23598.764087494197156f, + 23615.291279066041170f, 23631.821362788057741f, 23648.354337648564979f, + 23664.890202636761387f, 23681.428956742733135f, 23697.970598957443144f, + 23714.515128272738366f, 23731.062543681342504f, 23747.612844176863291f, + 23764.166028753777937f, 23780.722096407440404f, 23797.281046134085045f, + 23813.842876930815692f, 23830.407587795605650f, 23846.975177727301343f, + 23863.545645725622308f, 23880.118990791150281f, 23896.695211925336480f, + 23913.274308130497957f, 23929.856278409821243f, 23946.441121767347795f, + 23963.028837207988545f, 23979.619423737512989f, 23996.212880362549186f, + 24012.809206090583757f, 24029.408399929965526f, 24046.010460889898241f, + 24062.615387980433297f, 24079.223180212491570f, 24095.833836597827030f, + 24112.447356149063125f, 24129.063737879667315f, 24145.682980803951068f, + 24162.305083937080781f, 24178.930046295066859f, 24195.557866894767358f, + 24212.188544753884344f, 24228.822078890960256f, 24245.458468325388822f, + 24262.097712077396864f, 24278.739809168051579f, 24295.384758619260538f, + 24312.032559453768044f, 24328.683210695162416f, 24345.336711367857788f, + 24361.993060497108672f, 24378.652257108995400f, 24395.314300230442313f, + 24411.979188889192301f, 24428.646922113824985f, 24445.317498933745810f, + 24461.990918379193317f, 24478.667179481224593f, 24495.346281271726184f, + 24512.028222783406818f, 24528.713003049801046f, 24545.400621105265600f, + 24562.091075984975760f, 24578.784366724925349f, 24595.480492361926736f, + 24612.179451933614473f, 24628.881244478438020f, 24645.585869035654468f, + 24662.293324645343091f, 24679.003610348398070f, 24695.716725186513941f, + 24712.432668202211062f, 24729.151438438806508f, 24745.873034940435900f, + 24762.597456752031576f, 24779.324702919344418f, 24796.054772488925664f, + 24812.787664508123271f, 24829.523378025100101f, 24846.261912088819372f, + 24863.003265749033744f, 24879.747438056307146f, 24896.494428062003863f, + 24913.244234818277619f, 24929.996857378082495f, 24946.752294795165653f, + 24963.510546124078246f, 24980.271610420157231f, 24997.035486739525368f, + 25013.802174139113049f, 25030.571671676629194f, 25047.343978410572163f, + 25064.119093400237034f, 25080.897015705697413f, 25097.677744387812709f, + 25114.461278508239047f, 25131.247617129400169f, 25148.036759314516530f, + 25164.828704127583478f, 25181.623450633374887f, 25198.420997897450434f, + 25215.221344986144686f, 25232.024490966574376f, 25248.830434906627488f, + 25265.639175874974171f, 25282.450712941048550f, 25299.265045175070554f, + 25316.082171648024087f, 25332.902091431667941f, 25349.724803598532162f, + 25366.550307221914409f, 25383.378601375883591f, 25400.209685135268955f, + 25417.043557575678278f, 25433.880217773472395f, 25450.719664805783395f, + 25467.561897750507342f, 25484.406915686296998f, 25501.254717692572740f, + 25518.105302849511645f, 25534.958670238051127f, 25551.814818939888937f, + 25568.673748037479527f, 25585.535456614026771f, 25602.399943753502157f, + 25619.267208540619322f, 25636.137250060852239f, 25653.010067400431581f, + 25669.885659646326530f, 25686.764025886270247f, 25703.645165208734397f, + 25720.529076702947350f, 25737.415759458875982f, 25754.305212567243871f, + 25771.197435119516740f, 25788.092426207898825f, 25804.990184925343783f, + 25821.890710365547420f, 25838.794001622944052f, 25855.700057792717416f, + 25872.608877970775211f, 25889.520461253778194f, 25906.434806739118358f, + 25923.351913524922566f, 25940.271780710063467f, 25957.194407394137670f, + 25974.119792677476653f, 25991.047935661154042f, 26007.978835446963785f, + 26024.912491137441975f, 26041.848901835841389f, 26058.788066646160587f, + 26075.729984673107538f, 26092.674655022132356f, 26109.622076799409115f, + 26126.572249111828569f, 26143.525171067016345f, 26160.480841773314751f, + 26177.439260339790053f, 26194.400425876228837f, 26211.364337493145285f, + 26228.330994301766623f, 26245.300395414040395f, 26262.272539942627191f, + 26279.247427000918833f, 26296.225055703005637f, 26313.205425163701875f, + 26330.188534498538502f, 26347.174382823755877f, 26364.162969256307406f, + 26381.154292913852260f, 26398.148352914773568f, 26415.145148378149315f, + 26432.144678423777805f, 26449.146942172155832f, 26466.151938744493236f, + 26483.159667262701987f, 26500.170126849403459f, 26517.183316627921158f, + 26534.199235722277081f, 26551.217883257198991f, 26568.239258358120424f, + 26585.263360151173401f, 26602.290187763181166f, 26619.319740321676363f, + 26636.352016954882856f, 26653.387016791726637f, 26670.424738961824914f, + 26687.465182595493388f, 26704.508346823738975f, 26721.554230778267083f, + 26738.602833591467061f, 26755.654154396430386f, 26772.708192326928838f, + 26789.764946517432691f, 26806.824416103096155f, 26823.886600219761021f, + 26840.951498003960296f, 26858.019108592914563f, 26875.089431124517432f, + 26892.162464737364644f, 26909.238208570721326f, 26926.316661764547462f, + 26943.397823459472420f, 26960.481692796813149f, 26977.568268918574176f, + 26994.657550967422139f, 27011.749538086722168f, 27028.844229420497868f, + 27045.941624113464059f, 27063.041721311004949f, 27080.144520159181411f, + 27097.250019804727344f, 27114.358219395049673f, 27131.469118078235624f, + 27148.582715003030899f, 27165.699009318857861f, 27182.818000175815541f, + 27199.939686724665080f, 27217.064068116837007f, 27234.191143504427600f, + 27251.320912040202529f, 27268.453372877593210f, 27285.588525170693174f, + 27302.726368074268976f, 27319.866900743734732f, 27337.010122335181222f, + 27354.156032005357702f, 27371.304628911668260f, 27388.455912212182739f, + 27405.609881065625814f, 27422.766534631387913f, 27439.925872069507022f, + 27457.087892540683242f, 27474.252595206275146f, 27491.419979228292505f, + 27508.590043769399927f, 27525.762787992916856f, 27542.938211062810296f, + 27560.116312143705727f, 27577.297090400876186f, 27594.480545000242273f, + 27611.666675108383060f, 27628.855479892517906f, 27646.046958520513726f, + 27663.241110160888638f, 27680.437933982801042f, 27697.637429156067810f, + 27714.839594851131551f, 27732.044430239089706f, 27749.251934491687280f, + 27766.462106781298644f, 27783.674946280949371f, 27800.890452164301678f, + 27818.108623605654429f, 27835.329459779954050f, 27852.552959862779971f, + 27869.779123030344635f, 27887.007948459504405f, 27904.239435327745014f, + 27921.473582813196117f, 27938.710390094613103f, 27955.949856351391645f, + 27973.191980763549509f, 27990.436762511744746f, 28007.684200777272054f, + 28024.934294742040947f, 28042.187043588601227f, 28059.442446500128426f, + 28076.700502660427446f, 28093.961211253928923f, 28111.224571465692861f, + 28128.490582481401361f, 28145.759243487362255f, 28163.030553670509107f, + 28180.304512218393938f, 28197.581118319198140f, 28214.860371161725197f, + 28232.142269935389777f, 28249.426813830239553f, 28266.714002036929742f, + 28284.003833746744931f, 28301.296308151584526f, 28318.591424443959113f, + 28335.889181817001372f, 28353.189579464462440f, 28370.492616580704635f, + 28387.798292360701453f, 28405.106606000048487f, 28422.417556694945233f, + 28439.731143642206007f, 28457.047366039263579f, 28474.366223084147350f, + 28491.687713975512452f, 28509.011837912610645f, 28526.338594095304870f, + 28543.667981724069250f, 28560.999999999985448f, 28578.334648124731757f, + 28595.671925300604926f, 28613.011830730498332f, 28630.354363617909257f, + 28647.699523166942527f, 28665.047308582299593f, 28682.397719069289451f, + 28699.750753833817726f, 28717.106412082390307f, 28734.464693022120628f, + 28751.825595860711474f, 28769.189119806462259f, 28786.555264068279939f, + 28803.924027855664463f, 28821.295410378701490f, 28838.669410848087864f, + 28856.046028475102503f, 28873.425262471628230f, 28890.807112050129945f, + 28908.191576423672814f, 28925.578654805914994f, 28942.968346411096718f, + 28960.360650454054849f, 28977.755566150215600f, 28995.153092715590901f, + 29012.553229366785672f, 29029.955975320986909f, 29047.361329795974598f, + 29064.769292010107165f, 29082.179861182336026f, 29099.593036532187398f, + 29117.008817279780487f, 29134.427202645812940f, 29151.848191851571755f, + 29169.271784118911455f, 29186.697978670283192f, 29204.126774728705641f, + 29221.558171517790470f, 29238.992168261716870f, 29256.428764185249747f, + 29273.867958513725171f, 29291.309750473057647f, 29308.754139289747400f, + 29326.201124190854898f, 29343.650704404029966f, 29361.102879157482676f, + 29378.557647680012451f, 29396.015009200975328f, 29413.474962950309418f, + 29430.937508158523997f, 29448.402644056692225f, 29465.870369876469340f, + 29483.340684850070829f, 29500.813588210279704f, 29518.289079190453776f, + 29535.767157024511107f, 29553.247820946944557f, 29570.731070192807238f, + 29588.216903997723421f, 29605.705321597870352f, 29623.196322230000078f, + 29640.689905131428532f, 29658.186069540028257f, 29675.684814694235683f, + 29693.186139833047491f, 29710.690044196027884f, 29728.196527023297676f, + 29745.705587555527018f, 29763.217225033964496f, 29780.731438700397121f, + 29798.248227797183063f, 29815.767591567229829f, 29833.289529254005174f, + 29850.814040101529827f, 29868.341123354381125f, 29885.870778257693019f, + 29903.403004057145154f, 29920.937799998973787f, 29938.475165329975425f, + 29956.015099297481356f, 29973.557601149394031f, 29991.102670134147047f, + 30008.650305500741524f, 30026.200506498709728f, 30043.753272378144175f, + 30061.308602389683074f, 30078.866495784506697f, 30096.426951814351924f, + 30113.989969731494057f, 30131.555548788750457f, 30149.123688239491457f, + 30166.694387337629450f, 30184.267645337607973f, 30201.843461494434450f, + 30219.421835063640174f, 30237.002765301309410f, 30254.586251464057568f, + 30272.172292809045757f, 30289.760888593977143f, 30307.352038077089674f, + 30324.945740517159720f, 30342.541995173502073f, 30360.140801305966306f, + 30377.742158174944052f, 30395.346065041358088f, 30412.952521166665974f, + 30430.561525812863692f, 30448.173078242474730f, 30465.787177718560997f, + 30483.403823504719185f, 30501.023014865069854f, 30518.644751064271986f, + 30536.269031367515709f, 30553.895855040515016f, 30571.525221349518688f, + 30589.157129561306647f, 30606.791578943175409f, 30624.428568762963550f, + 30642.068098289029876f, 30659.710166790260701f, 30677.354773536069843f, + 30695.001917796391353f, 30712.651598841686791f, 30730.303815942945221f, + 30747.958568371675938f, 30765.615855399912107f, 30783.275676300210762f, + 30800.938030345645529f, 30818.602916809813905f, 30836.270334966837254f, + 30853.940284091353533f, 30871.612763458520931f, 30889.287772344010591f, + 30906.965310024024802f, 30924.645375775271532f, 30942.327968874982616f, + 30960.013088600902847f, 30977.700734231293609f, 30995.390905044929241f, + 31013.083600321100676f, 31030.778819339619076f, 31048.476561380797648f, + 31066.176825725469826f, 31083.879611654978362f, 31101.584918451178964f, + 31119.292745396440296f, 31137.003091773636697f, 31154.715956866155466f, + 31172.431339957893215f, 31190.149240333259513f, 31207.869657277162332f, + 31225.592590075022599f, 31243.318038012770558f, 31261.046000376838492f, + 31278.776476454171643f, 31296.509465532210015f, 31314.244966898910207f, + 31331.982979842719942f, 31349.723503652599902f, 31367.466537618012808f, + 31385.212081028923421f, 31402.960133175794908f, 31420.710693349596113f, + 31438.463760841790645f, 31456.219334944351431f, 31473.977414949742524f, + 31491.738000150933658f, 31509.501089841389330f, 31527.266683315068803f, + 31545.034779866437020f, 31562.805378790450050f, 31580.578479382562364f, + 31598.354080938719562f, 31616.132182755369286f, 31633.912784129450301f, + 31651.695884358396142f, 31669.481482740131469f, 31687.269578573075705f, + 31705.060171156143042f, 31722.853259788735159f, 31740.648843770748499f, + 31758.446922402566997f, 31776.247494985065714f, 31794.050560819614475f, + 31811.856119208059681f, 31829.664169452753413f, 31847.474710856520687f, + 31865.287742722684925f, 31883.103264355046122f, 31900.921275057899038f, + 31918.741774136018648f, 31936.564760894671053f, 31954.390234639598930f, + 31972.218194677039719f, 31990.048640313703800f, 32007.881570856792678f, + 32025.716985613984434f, 32043.554883893444639f, 32061.395265003815439f, + 32079.238128254222829f, 32097.083472954269382f, 32114.931298414048797f, + 32132.781603944116796f, 32150.634388855523866f, 32168.489652459789795f, + 32186.347394068914582f, 32204.207612995371164f, 32222.070308552119968f, + 32239.935480052583443f, 32257.803126810671529f, 32275.673248140767100f, + 32293.545843357718695f, 32311.420911776862340f, 32329.298452713996085f, + 32347.178465485394554f, 32365.060949407812586f, 32382.945903798463405f, + 32400.833327975040447f, 32418.723221255706449f, 32436.615582959093445f, + 32454.510412404306408f, 32472.407708910915972f, 32490.307471798965707f, + 32508.209700388961210f, 32526.114394001877372f, 32544.021551959165663f, + 32561.931173582732299f, 32579.843258194956434f, 32597.757805118679244f, + 32615.674813677211205f, 32633.594283194328455f, 32651.516212994258240f, + 32669.440602401711658f, 32687.367450741847279f, 32705.296757340296608f, + 32723.228521523145901f, 32741.162742616943433f, 32759.099419948703144f, + 32777.038552845900995f, 32794.980140636464057f, 32812.924182648792339f, + 32830.870678211729683f, 32848.819626654592867f, 32866.771027307149780f, + 32884.724879499619419f, 32902.681182562686445f, 32920.639935827493900f, + 32938.601138625643216f, 32956.564790289179655f, 32974.530890150606865f, + 32992.499437542894157f, 33010.470431799447397f, 33028.443872254145390f, + 33046.419758241310774f, 33064.398089095710020f, 33082.378864152582537f, + 33100.362082747589739f, 33118.347744216880528f, 33136.335847897025815f, + 33154.326393125062168f, 33172.319379238469992f, 33190.314805575173523f, + 33208.312671473555383f, 33226.312976272442029f, 33244.315719311111025f, + 33262.320899929283769f, 33280.328517467125494f, 33298.338571265259816f, + 33316.351060664746910f, 33334.365985007090785f, 33352.383343634239282f, + 33370.403135888591351f, 33388.425361112989776f, 33406.450018650721177f, + 33424.477107845501450f, 33442.506628041512158f, 33460.538578583349590f, + 33478.572958816082973f, 33496.609768085188989f, 33514.649005736617255f, + 33532.690671116739395f, 33550.734763572356314f, 33568.781282450734579f, + 33586.830227099562762f, 33604.881596866973268f, 33622.935391101527784f, + 33640.991609152239107f, 33659.050250368542038f, 33677.111314100322488f, + 33695.174799697881099f, 33713.240706511984172f, 33731.309033893805463f, + 33749.379781194969837f, 33767.452947767531441f, 33785.528532963973703f, + 33803.606536137209332f, 33821.686956640602148f, 33839.769793827937974f, + 33857.855047053424641f, 33875.942715671706537f, 33894.032799037871882f, + 33912.125296507430903f, 33930.220207436315832f, 33948.317531180888182f, + 33966.417267097960575f, 33984.519414544745814f, 34002.623972878900531f, + 34020.730941458510642f, 34038.840319642076793f, 34056.952106788536184f, + 34075.066302257255302f, 34093.182905408015358f, 34111.301915601026849f, + 34129.423332196929550f, 34147.547154556785244f, 34165.673382042077719f, + 34183.802014014720044f, 34201.933049837032740f, 34220.066488871780166f, + 34238.202330482141406f, 34256.340574031702999f, 34274.481218884495320f, + 34292.624264404948917f, 34310.769709957938176f, 34328.917554908730381f, + 34347.067798623029375f, 34365.220440466953733f, 34383.375479807051306f, + 34401.532916010262852f, 34419.692748443972960f, 34437.854976475966396f, + 34456.019599474449933f, 34474.186616808059625f, 34492.356027845817152f, + 34510.527831957188027f, 34528.702028512052493f, 34546.878616880676418f, + 34565.057596433769504f, 34583.238966542448907f, 34601.422726578231959f, + 34619.608875913065276f, 34637.797413919295650f, 34655.988339969691879f, + 34674.181653437422938f, 34692.377353696079808f, 34710.575440119668201f, + 34728.775912082579453f, 34746.978768959648733f, 34765.184010126082285f, + 34783.391634957537462f, 34801.601642830049968f, 34819.814033120062959f, + 34838.028805204456148f, 34856.245958460480324f, 34874.465492265822832f, + 34892.687405998556642f, 34910.911699037176732f, 34929.138370760563703f, + 34947.367420548027440f, 34965.598847779270727f, 34983.832651834389253f, + 35002.068832093907986f, 35020.307387938737520f, 35038.548318750188628f, + 35056.791623909979535f, 35075.037302800250473f, 35093.285354803512746f, + 35111.535779302685114f, 35129.788575681115617f, 35148.043743322516093f, + 35166.301281611013110f, 35184.561189931140689f, 35202.823467667825753f, + 35221.088114206388127f, 35239.355128932555090f, 35257.624511232446821f, + 35275.896260492583679f, 35294.170376099886198f, 35312.446857441667817f, + 35330.725703905627597f, 35349.006914879886608f, 35367.290489752944268f, + 35385.576427913685620f, 35403.864728751417715f, 35422.155391655811400f, + 35440.448416016966803f, 35458.743801225340576f, 35477.041546671804099f, + 35495.341651747621654f, 35513.644115844435873f, 35531.948938354304119f, + 35550.256118669654825f, 35568.565656183309329f, 35586.877550288496423f, + 35605.191800378815969f, 35623.508405848268012f, 35641.827366091238218f, + 35660.148680502505158f, 35678.472348477233027f, 35696.798369410978921f, + 35715.126742699678289f, 35733.457467739659478f, 35751.790543927643739f, + 35770.125970660737948f, 35788.463747336420056f, 35806.803873352568189f, + 35825.146348107453377f, 35843.491170999710448f, 35861.838341428367130f, + 35880.187858792851330f, 35898.539722492954752f, 35916.893931928862003f, + 35935.250486501128762f, 35953.609385610718164f, 35971.970628658957139f, + 35990.334215047558246f, 36008.700144178612391f, 36027.068415454596106f, + 36045.439028278371552f, 36063.811982053164684f, 36082.187276182608912f, + 36100.564910070694168f, 36118.944883121788735f, 36137.327194740653795f, + 36155.711844332428882f, 36174.098831302617327f, 36192.488155057115364f, + 36210.879815002190298f, 36229.273810544473235f, 36247.670141091002733f, + 36266.068806049166596f, 36284.469804826738255f, 36302.873136831862212f, + 36321.278801473068597f, 36339.686798159251339f, 36358.097126299682714f, + 36376.509785304013349f, 36394.924774582264945f, 36413.342093544815725f, + 36431.761741602444090f, 36450.183718166292238f, 36468.608022647858888f, + 36487.034654459028388f, 36505.463613012063433f, 36523.894897719583241f, + 36542.328507994578104f, 36560.764443250409386f, 36579.202702900831355f, + 36597.643286359925696f, 36616.086193042181549f, 36634.531422362437297f, + 36652.978973735895124f, 36671.428846578142839f, 36689.881040305124770f, + 36708.335554333149048f, 36726.792388078902150f, 36745.251540959427075f, + 36763.713012392137898f, 36782.176801794812491f, 36800.642908585592522f, + 36819.111332182990736f, 36837.582072005869122f, 36856.055127473482571f, + 36874.530498005420668f, 36893.008183021651348f, 36911.488181942506344f, + 36929.970494188673911f, 36948.455119181206101f, 36966.942056341518764f, + 36985.431305091391550f, 37003.922864852960629f, 37022.416735048733244f, + 37040.912915101558610f, 37059.411404434657015f, 37077.912202471619821f, + 37096.415308636387635f, 37114.920722353243036f, 37133.428443046861503f, + 37151.938470142253209f, 37170.450803064784850f, 37188.965441240208747f, + 37207.482384094597364f, 37226.001631054401514f, 37244.523181546428532f, + 37263.047034997842275f, 37281.573190836148569f, 37300.101648489224317f, + 37318.632407385295664f, 37337.165466952945280f, 37355.700826621112355f, + 37374.238485819085327f, 37392.778443976509152f, 37411.320700523385312f, + 37429.865254890057258f, 37448.412106507232238f, 37466.961254805966746f, + 37485.512699217681075f, 37504.066439174115658f, 37522.622474107403832f, + 37541.180803449991799f, 37559.741426634696836f, 37578.304343094692740f, + 37596.869552263488004f, 37615.437053574940364f, 37634.006846463271359f, + 37652.578930363044492f, 37671.153304709165241f, 37689.729968936895602f, + 37708.308922481846821f, 37726.890164779964834f, 37745.473695267559378f, + 37764.059513381274883f, 37782.647618558112299f, 37801.238010235414549f, + 37819.830687850859249f, 37838.425650842495088f, 37857.022898648690898f, + 37875.622430708172033f, 37894.224246460013092f, 37912.828345343616093f, + 37931.434726798746851f, 37950.043390265505877f, 37968.654335184328374f, + 37987.267560995998792f, 38005.883067141665379f, 38024.500853062774695f, + 38043.120918201158929f, 38061.743261998963135f, 38080.367883898681612f, + 38098.994783343157906f, 38117.623959775562980f, 38136.255412639417045f, + 38154.889141378575005f, 38173.525145437233732f, 38192.163424259939347f, + 38210.803977291550837f, 38229.446803977283707f, 38248.091903762702714f, + 38266.739276093685476f, 38285.388920416466135f, 38304.040836177606252f, + 38322.695022824002081f, 38341.351479802899121f, 38360.010206561863015f, + 38378.671202548815927f, 38397.334467211992887f, 38415.999999999978172f, + 38434.667800361683476f, 38453.337867746369739f, 38472.010201603610767f, + 38490.684801383336890f, 38509.361666535784025f, 38528.040796511551889f, + 38546.722190761553065f, 38565.405848737034830f, 38584.091769889593706f, + 38602.779953671131807f, 38621.470399533907766f, 38640.163106930485810f, + 38658.858075313793961f, 38677.555304137058556f, 38696.254792853862455f, + 38714.956540918094106f, 38733.660547783991206f, 38752.366812906111591f, + 38771.075335739347793f, 38789.786115738919761f, 38808.499152360367589f, + 38827.214445059573336f, 38845.931993292739207f, 38864.651796516387549f, + 38883.373854187382676f, 38902.098165762916324f, 38920.824730700485816f, + 38939.553548457937723f, 38958.284618493431481f, 38977.017940265461220f, + 38995.753513232833939f, 39014.491336854698602f, 39033.231410590517044f, + 39051.973733900078514f, 39070.718306243485131f, 39089.465127081188257f, + 39108.214195873944846f, 39126.965512082831992f, 39145.719075169261487f, + 39164.474884594965260f, 39183.232939821988111f, 39201.993240312709531f, + 39220.755785529814602f, 39239.520574936330377f, 39258.287607995589497f, + 39277.056884171244747f, 39295.828402927290881f, 39314.602163728006417f, + 39333.378166038019117f, 39352.156409322269610f, 39370.936893046004116f, + 39389.719616674810823f, 39408.504579674583510f, 39427.291781511521549f, + 39446.081221652173554f, 39464.872899563371902f, 39483.666814712290943f, + 39502.462966566410614f, 39521.261354593538272f, 39540.061978261779586f, + 39558.864837039567647f, 39577.669930395655683f, 39596.477257799109793f, + 39615.286818719301664f, 39634.098612625923124f, 39652.912638988993422f, + 39671.728897278822842f, 39690.547386966063641f, 39709.368107521651837f, + 39728.191058416858141f, 39747.016239123258856f, 39765.843649112750427f, + 39784.673287857527612f, 39803.505154830105312f, 39822.339249503318570f, + 39841.175571350293467f, 39860.014119844498055f, 39878.854894459676871f, + 39897.697894669909147f, 39916.543119949579705f, 39935.390569773371681f, + 39954.240243616302905f, 39973.092140953674971f, 39991.946261261116888f, + 40010.802604014548706f, 40029.661168690225168f, 40048.521954764677503f, + 40067.384961714778910f, 40086.250189017679077f, 40105.117636150855105f, + 40123.987302592089691f, 40142.859187819471117f, 40161.733291311378707f, + 40180.609612546526478f, 40199.488151003912208f, 40218.368906162853818f, + 40237.251877502960269f, 40256.137064504153386f, 40275.024466646667861f, + 40293.914083411029424f, 40312.805914278083947f, 40331.699958728961064f, + 40350.596216245103278f, 40369.494686308273231f, 40388.395368400510051f, + 40407.298262004173012f, 40426.203366601919697f, 40445.110681676706008f, + 40464.020206711793435f, 40482.931941190756334f, 40501.845884597445547f, + 40520.762036416032061f, 40539.680396130985173f, 40558.600963227072498f, + 40577.523737189367239f, 40596.448717503233638f, 40615.375903654341528f, + 40634.305295128659054f, 40653.236891412452678f, 40672.170691992294451f, + 40691.106696355047461f, 40710.044903987873113f, 40728.985314378238400f, + 40747.927927013901353f, 40766.872741382918321f, 40785.819756973651238f, + 40804.768973274745804f, 40823.720389775160584f, 40842.674005964130629f, + 40861.629821331211133f, 40880.587835366226500f, 40899.548047559328552f, + 40918.510457400931045f, 40937.475064381760603f, 40956.441867992849438f, + 40975.410867725498974f, 40994.382063071323500f, 41013.355453522235621f, + 41032.331038570417149f, 41051.308817708362767f, 41070.288790428858192f, + 41089.270956224987458f, 41108.255314590111084f, 41127.241865017887903f, + 41146.230607002289617f, 41165.221540037542582f, 41184.214663618193299f, + 41203.209977239079308f, 41222.207480395307357f, 41241.207172582297062f, + 41260.209053295751801f, 41279.213122031658713f, 41298.219378286303254f, + 41317.227821556254639f, 41336.238451338380401f, 41355.251267129831831f, + 41374.266268428036710f, 41393.283454730742960f, 41412.302825535953161f, + 41431.324380341982760f, 41450.348118647416413f, 41469.374039951144368f, + 41488.402143752326083f, 41507.432429550426605f, 41526.464896845187468f, + 41545.499545136626693f, 41564.536373925075168f, 41583.575382711125712f, + 41602.616570995662187f, 41621.659938279874041f, 41640.705484065205383f, + 41659.753207853405911f, 41678.803109146494535f, 41697.855187446803029f, + 41716.909442256910552f, 41735.965873079709127f, 41755.024479418359988f, + 41774.085260776315408f, 41793.148216657296871f, 41812.213346565331449f, + 41831.280650004708150f, 41850.350126480014296f, 41869.421775496106420f, + 41888.495596558132092f, 41907.571589171515370f, 41926.649752841956797f, + 41945.730087075462507f, 41964.812591378286015f, 41983.897265256979153f, + 42002.984108218377514f, 42022.073119769593177f, 42041.164299418007431f, + 42060.257646671307157f, 42079.353161037419341f, 42098.450842024591111f, + 42117.550689141324256f, 42136.652701896404324f, 42155.756879798893351f, + 42174.863222358137136f, 42193.971729083757964f, 42213.082399485654605f, + 42232.195233074002317f, 42251.310229359245568f, 42270.427387852127140f, + 42289.546708063644473f, 42308.668189505078772f, 42327.791831687995000f, + 42346.917634124227334f, 42366.045596325886436f, 42385.175717805352178f, + 42404.307998075295473f, 42423.442436648641888f, 42442.579033038608031f, + 42461.717786758672446f, 42480.858697322597436f, 42500.001764244421793f, + 42519.146987038446241f, 42538.294365219247993f, 42557.443898301688023f, + 42576.595585800881963f, 42595.749427232236485f, 42614.905422111420194f, + 42634.063569954370905f, 42653.223870277317474f, 42672.386322596728860f, + 42691.550926429379615f, 42710.717681292291672f, 42729.886586702763452f, + 42749.057642178362585f, 42768.230847236940463f, 42787.406201396610413f, + 42806.583704175740422f, 42825.763355092989514f, 42844.945153667285922f, + 42864.129099417805264f, 42883.315191864014196f, 42902.503430525648582f, + 42921.693814922691672f, 42940.886344575410476f, 42960.081019004348491f, + 42979.277837730296596f, 42998.476800274322159f, 43017.677906157769030f, + 43036.881154902228445f, 43056.086546029582678f, 43075.294079061961384f, + 43094.503753521763429f, 43113.715568931664166f, 43132.929524814600882f, + 43152.145620693765522f, 43171.363856092619244f, 43190.584230534906965f, + 43209.806743544620986f, 43229.031394646015542f, 43248.258183363621356f, + 43267.487109222223808f, 43286.718171746884764f, 43305.951370462906198f, + 43325.186704895881121f, 43344.424174571649928f, 43363.663779016322223f, + 43382.905517756262270f, 43402.149390318103542f, 43421.395396228748723f, + 43440.643535015347879f, 43459.893806205320288f, 43479.146209326347162f, + 43498.400743906378921f, 43517.657409473606094f, 43536.916205556495697f, + 43556.177131683783955f, 43575.440187384439923f, 43594.705372187723697f, + 43613.972685623135476f, 43633.242127220437396f, 43652.513696509668080f, + 43671.787393021098978f, 43691.063216285270755f, 43710.341165833000559f, + 43729.621241195345647f, 43748.903441903625207f, 43768.187767489413091f, + 43787.474217484552355f, 43806.762791421126167f, 43826.053488831501454f, + 43845.346309248277976f, 43864.641252204324701f, 43883.938317232765257f, + 43903.237503866977931f, 43922.538811640595668f, 43941.842240087513346f, + 43961.147788741880504f, 43980.455457138101337f, 43999.765244810834702f, + 44019.077151295001386f, 44038.391176125755010f, 44057.707318838540232f, + 44077.025578969019989f, 44096.345956053140981f, 44115.668449627082737f, + 44134.993059227286722f, 44154.319784390456334f, 44173.648624653535080f, + 44192.979579553728399f, 44212.312648628489114f, 44231.647831415531982f, + 44250.985127452804591f, 44270.324536278538289f, 44289.666057431182708f, + 44309.009690449463960f, 44328.355434872355545f, 44347.703290239063790f, + 44367.053256089078786f, 44386.405331962108903f, 44405.759517398138996f, + 44425.115811937386752f, 44444.474215120331792f, 44463.834726487693843f, + 44483.197345580461842f, 44502.562071939843008f, 44521.928905107328319f, + 44541.297844624634308f, 44560.668890033732168f, 44580.042040876847750f, + 44599.417296696454287f, 44618.794657035272394f, 44638.174121436255518f, + 44657.555689442640869f, 44676.939360597869381f, 44696.325134445673029f, + 44715.713010530002066f, 44735.102988395054126f, 44754.495067585296056f, + 44773.889247645420255f, 44793.285528120373783f, 44812.683908555343805f, + 44832.084388495779422f, 44851.486967487355287f, 44870.891645076015266f, + 44890.298420807914226f, 44909.707294229490799f, 44929.118264887409168f, + 44948.531332328566350f, 44967.946496100135846f, 44987.363755749502161f, + 45006.783110824326286f, 45026.204560872472939f, 45045.628105442097876f, + 45065.053744081560581f, 45084.481476339489745f, 45103.911301764739619f, + 45123.343219906426384f, 45142.777230313884502f, 45162.213332536710368f, + 45181.651526124733209f, 45201.091810628036910f, 45220.534185596923635f, + 45239.978650581964757f, 45259.425205133957206f, 45278.873848803938017f, + 45298.324581143191608f, 45317.777401703235228f, 45337.232310035848059f, + 45356.689305693020287f, 45376.148388226996758f, 45395.609557190269697f, + 45415.072812135556887f, 45434.538152615823492f, 45454.005578184282058f, + 45473.475088394356135f, 45492.946682799745759f, 45512.420360954361968f, + 45531.896122412363184f, 45551.373966728155210f, 45570.853893456362130f, + 45590.335902151869959f, 45609.819992369775719f, 45629.306163665438362f, + 45648.794415594442398f, 45668.284747712612443f, 45687.777159576005943f, + 45707.271650740920450f, 45726.768220763893623f, 45746.266869201695954f, + 45765.767595611323486f, 45785.270399550034199f, 45804.775280575297074f, + 45824.282238244821201f, 45843.791272116570326f, 45863.302381748719199f, + 45882.815566699682677f, 45902.330826528130274f, 45921.848160792935232f, + 45941.367569053225452f, 45960.889050868354389f, 45980.412605797930155f, + 45999.938233401757316f, 46019.465933239902370f, 46038.995704872657370f, + 46058.527547860547202f, 46078.061461764329579f, 46097.597446145002323f, + 46117.135500563774258f, 46136.675624582108867f, 46156.217817761702463f, + 46175.762079664462362f, 46195.308409852543264f, 46214.856807888332696f, + 46234.407273334443744f, 46253.959805753715045f, 46273.514404709239898f, + 46293.071069764315325f, 46312.629800482478458f, 46332.190596427499258f, + 46351.753457163380517f, 46371.318382254350581f, 46390.885371264863352f, + 46410.454423759620113f, 46430.025539303525875f, 46449.598717461733031f, + 46469.173957799619529f, 46488.751259882781596f, 46508.330623277070117f, + 46527.912047548532428f, 46547.495532263470523f, 46567.081076988397399f, + 46586.668681290058885f, 46606.258344735433639f, 46625.850066891718598f, + 46645.443847326350806f, 46665.039685606985586f, 46684.637581301496539f, + 46704.237533978004649f, 46723.839543204841902f, 46743.443608550573117f, + 46763.049729583988665f, 46782.657905874104472f, 46802.268136990162020f, + 46821.880422501628345f, 46841.494761978196038f, 46861.111154989775969f, + 46880.729601106526388f, 46900.350099898794724f, 46919.972650937190338f, + 46939.597253792526317f, 46959.223908035841305f, 46978.852613238399499f, + 46998.483368971690652f, 47018.116174807430070f, 47037.751030317551340f, + 47057.387935074213601f, 47077.026888649808825f, 47096.667890616939985f, + 47116.310940548428334f, 47135.956038017327955f, 47155.603182596918487f, + 47175.252373860697844f, 47194.903611382374947f, 47214.556894735898823f, + 47234.212223495422222f, 47253.869597235338006f, 47273.529015530250035f, + 47293.190477954980452f, 47312.853984084576950f, 47332.519533494305506f, + 47352.187125759657647f, 47371.856760456343181f, 47391.528437160297472f, + 47411.202155447652331f, 47430.877914894786954f, 47450.555715078298817f, + 47470.235555574981845f, 47489.917435961862793f, 47509.601355816201249f, + 47529.287314715453249f, 47548.975312237307662f, 47568.665347959671635f, + 47588.357421460656042f, 47608.051532318604586f, 47627.747680112071976f, + 47647.445864419845748f, 47667.146084820909891f, 47686.848340894473949f, + 47706.552632219973020f, 47726.258958377045929f, 47745.967318945557054f, + 47765.677713505581778f, 47785.390141637428314f, 47805.104602921601327f, + 47824.821096938823757f, 47844.539623270044103f, 47864.260181496429141f, + 47883.982771199349372f, 47903.707391960393579f, 47923.434043361376098f, + 47943.162724984307715f, 47962.893436411439325f, 47982.626177225218271f, + 48002.360947008310177f, 48022.097745343598945f, 48041.836571814172203f, + 48061.577426003350411f, 48081.320307494650478f, 48101.065215871814871f, + 48120.812150718789781f, 48140.561111619739677f, 48160.312098159047309f, + 48180.065109921306430f, 48199.820146491307241f, 48219.577207454072777f, + 48239.336292394844349f, 48259.097400899045169f, 48278.860532552338555f, + 48298.625686940591550f, 48318.392863649874926f, 48338.162062266485009f, + 48357.933282376914576f, 48377.706523567889235f, 48397.481785426316492f, + 48417.259067539343960f, 48437.038369494308427f, 48456.819690878764959f, + 48476.603031280486903f, 48496.388390287451330f, 48516.175767487839039f, + 48535.965162470041832f, 48555.756574822684343f, 48575.550004134565825f, + 48595.345449994718365f, 48615.142911992377776f, 48634.942389716990874f, + 48654.743882758200925f, 48674.547390705876751f, 48694.352913150090899f, + 48714.160449681112368f, 48733.969999889435712f, 48753.781563365759212f, + 48773.595139700984873f, 48793.410728486211156f, 48813.228329312769347f, + 48833.047941772187187f, 48852.869565456188866f, 48872.693199956716853f, + 48892.518844865924621f, 48912.346499776154815f, 48932.176164279975637f, + 48952.007837970151741f, 48971.841520439658780f, 48991.677211281676136f, + 49011.514910089586920f, 49031.354616456977965f, 49051.196329977654386f, + 49071.040050245610473f, 49090.885776855058793f, 49110.733509400408366f, + 49130.583247476279212f, 49150.434990677487804f, 49170.288738599061617f, + 49190.144490836239129f, 49210.002246984440717f, 49229.862006639326864f, + 49249.723769396718126f, 49269.587534852675162f, 49289.453302603447810f, + 49309.321072245482355f, 49329.190843375450640f, 49349.062615590191854f, + 49368.936388486785290f, 49388.812161662492144f, 49408.689934714784613f, + 49428.569707241324068f, 49448.451478839990159f, 49468.335249108866265f, + 49488.221017646210385f, 49508.108784050520626f, 49527.998547920469719f, + 49547.890308854934119f, 49567.784066453008563f, 49587.679820313976961f, + 49607.577570037312398f, 49627.477315222720790f, 49647.379055470075400f, + 49667.282790379460494f, 49687.188519551178615f, 49707.096242585706932f, + 49727.005959083740890f, 49746.917668646165112f, 49766.831370874067943f, + 49786.747065368734184f, 49806.664751731659635f, 49826.584429564514721f, + 49846.506098469202698f, 49866.429758047794166f, 49886.355407902578008f, + 49906.283047636032279f, 49926.212676850846037f, 49946.144295149882964f, + 49966.077902136225021f, 49986.013497413150617f, 50005.951080584134615f, + 50025.890651252833777f, 50045.832209023123141f, 50065.775753499066923f, + 50085.721284284933063f, 50105.668800985164125f, 50125.618303204428230f, + 50145.569790547575394f, 50165.523262619652087f, 50185.478719025901228f, + 50205.436159371769463f, 50225.395583262892615f, 50245.356990305102954f, + 50265.320380104429205f, 50285.285752267103817f, 50305.253106399533863f, + 50325.222442108337418f, 50345.193759000329010f, 50365.167056682519615f, + 50385.142334762102109f, 50405.119592846473097f, 50425.098830543218355f, + 50445.080047460127389f, 50465.063243205178878f, 50485.048417386540677f, + 50505.035569612577092f, 50525.024699491856154f, 50545.015806633127795f, + 50565.008890645338397f, 50585.003951137630793f, 50605.000987719329714f, + 50624.999999999970896f, 50645.000987589264696f, 50665.003950097132474f, + 50685.008887133677490f, 50705.015798309192178f, 50725.024683234165423f, + 50745.035541519282560f, 50765.048372775410826f, 50785.063176613621181f, + 50805.079952645159210f, 50825.098700481488777f, 50845.119419734241092f, + 50865.142110015243816f, 50885.166770936521061f, 50905.193402110278839f, + 50925.222003148934164f, 50945.252573665071395f, 50965.285113271471346f, + 50985.319621581118554f, 51005.356098207172181f, 51025.394542762980564f, + 51045.434954862095765f, 51065.477334118244471f, 51085.521680145357095f, + 51105.567992557545949f, 51125.616270969112520f, 51145.666514994540194f, + 51165.718724248523358f, 51185.772898345916474f, 51205.829036901777727f, + 51225.887139531361754f, 51245.947205850105092f, 51266.009235473618901f, + 51286.073228017718066f, 51306.139183098399371f, 51326.207100331856054f, + 51346.276979334448697f, 51366.348819722756161f, 51386.422621113510104f, + 51406.498383123653184f, 51426.576105370309961f, 51446.655787470786890f, + 51466.737429042586882f, 51486.821029703380191f, 51506.906589071048074f, + 51526.994106763631862f, 51547.083582399391162f, 51567.175015596738376f, + 51587.268405974296911f, 51607.363753150857519f, 51627.461056745414680f, + 51647.560316377130221f, 51667.661531665362418f, 51687.764702229651448f, + 51707.869827689726662f, 51727.976907665499311f, 51748.085941777055268f, + 51768.196929644676857f, 51788.309870888835576f, 51808.424765130170272f, + 51828.541611989523517f, 51848.660411087905231f, 51868.781162046514510f, + 51888.903864486739621f, 51909.028518030143459f, 51929.155122298485367f, + 51949.283676913684758f, 51969.414181497872050f, 51989.546635673345008f, + 52009.681039062590571f, 52029.817391288263025f, 52049.955691973213106f, + 52070.095940740480728f, 52090.238137213273149f, 52110.382281014986802f, + 52130.528371769200021f, 52150.676409099665761f, 52170.826392630333430f, + 52190.978321985319781f, 52211.132196788930742f, 52231.288016665654141f, + 52251.445781240145152f, 52271.605490137269953f, 52291.767142982040241f, + 52311.930739399664162f, 52332.096279015546315f, 52352.263761455244094f, + 52372.433186344518617f, 52392.604553309283801f, 52412.777861975664564f, + 52432.953111969945894f, 52453.130302918594680f, 52473.309434448274260f, + 52493.490506185793492f, 52513.673517758179514f, 52533.858468792604981f, + 52554.045358916446276f, 52574.234187757254404f, 52594.424954942740442f, + 52614.617660100811918f, 52634.812302859558258f, 52655.008882847228961f, + 52675.207399692269973f, 52695.407853023294592f, 52715.610242469098011f, + 52735.814567658657325f, 52756.020828221109696f, 52776.229023785803292f, + 52796.439153982224525f, 52816.651218440056255f, 52836.865216789170518f, + 52857.081148659599421f, 52877.299013681549695f, 52897.518811485424521f, + 52917.740541701772599f, 52937.964203961353633f, 52958.189797895080119f, + 52978.417323134046455f, 52998.646779309528938f, 53018.878166052978486f, + 53039.111482996006089f, 53059.346729770419188f, 53079.583906008192571f, + 53099.823011341482925f, 53120.064045402599731f, 53140.307007824063476f, + 53160.551898238532885f, 53180.798716278870415f, 53201.047461578091315f, + 53221.298133769400010f, 53241.550732486175548f, 53261.805257361964323f, + 53282.061708030487353f, 53302.320084125640278f, 53322.580385281493363f, + 53342.842611132298771f, 53363.106761312468734f, 53383.372835456597386f, + 53403.640833199453482f, 53423.910754175973125f, 53444.182598021259764f, + 53464.456364370613301f, 53484.732052859479154f, 53505.009663123499195f, + 53525.289194798468088f, 53545.570647520362400f, 53565.854020925333316f, + 53586.139314649699372f, 53606.426528329953726f, 53626.715661602764158f, + 53647.006714104958519f, 53667.299685473546560f, 53687.594575345719932f, + 53707.891383358815801f, 53728.190109150360513f, 53748.490752358055033f, + 53768.793312619753124f, 53789.097789573497721f, 53809.404182857484557f, + 53829.712492110105813f, 53850.022716969899193f, 53870.334857075584296f, + 53890.648912066055345f, 53910.964881580366637f, 53931.282765257739811f, + 53951.602562737585686f, 53971.924273659460596f, 53992.247897663110052f, + 54012.573434388439637f, 54032.900883475529554f, 54053.230244564620079f, + 54073.561517296133388f, 54093.894701310644450f, 54114.229796248910134f, + 54134.566801751854655f, 54154.905717460569576f, 54175.246543016313808f, + 54195.589278060506331f, 54215.933922234755300f, 54236.280475180814392f, + 54256.628936540626455f, 54276.979305956279859f, 54297.331583070044871f, + 54317.685767524359107f, 54338.041858961827529f, 54358.399857025215169f, + 54378.759761357454408f, 54399.121571601666801f, 54419.485287401104870f, + 54439.850908399224863f, 54460.218434239613998f, 54480.587864566055941f, + 54500.959199022479879f, 54521.332437252996897f, 54541.707578901878151f, + 54562.084623613554868f, 54582.463571032640175f, 54602.844420803885441f, + 54623.227172572245763f, 54643.611825982807204f, 54663.998380680837727f, + 54684.386836311772640f, 54704.777192521207326f, 54725.169448954897234f, + 54745.563605258772441f, 54765.959661078923091f, 54786.357616061613953f, + 54806.757469853255316f, 54827.159222100439365f, 54847.562872449903807f, + 54867.968420548582799f, 54888.375866043534188f, 54908.785208582012274f, + 54929.196447811416874f, 54949.609583379322430f, 54970.024614933463454f, + 54990.441542121727252f, 55010.860364592190308f, 55031.281081993060070f, + 55051.703693972733163f, 55072.128200179759006f, 55092.554600262839813f, + 55112.982893870874250f, 55133.413080652877397f, 55153.845160258060787f, + 55174.279132335788745f, 55194.714996535585669f, 55215.152752507143305f, + 55235.592399900298915f, 55256.033938365078939f, 55276.477367551655334f, + 55296.922687110360130f, 55317.369896691685426f, 55337.818995946305222f, + 55358.269984525024483f, 55378.722862078830076f, 55399.177628258868936f, + 55419.634282716440794f, 55440.092825103012729f, 55460.553255070204614f, + 55481.015572269803670f, 55501.479776353764464f, 55521.945866974187084f, + 55542.413843783338962f, 55562.883706433654879f, 55583.355454577715136f, + 55603.829087868260103f, 55624.304605958219327f, 55644.782008500638767f, + 55665.261295148753561f, 55685.742465555951640f, 55706.225519375773729f, + 55726.710456261927902f, 55747.197275868275028f, 55767.685977848843322f, + 55788.176561857813795f, 55808.669027549527527f, 55829.163374578478397f, + 55849.659602599327627f, 55870.157711266889237f, 55890.657700236144592f, + 55911.159569162220578f, 55931.663317700411426f, 55952.168945506164164f, + 55972.676452235085890f, 55993.185837542943773f, 56013.697101085650502f, + 56034.210242519300664f, 56054.725261500119814f, 56075.242157684508129f, + 56095.760930729011307f, 56116.281580290342390f, 56136.804106025367219f, + 56157.328507591104426f, 56177.854784644739993f, 56198.382936843598145f, + 56218.912963845185004f, 56239.444865307137661f, 56259.978640887267829f, + 56280.514290243525465f, 56301.051813034042425f, 56321.591208917081531f, + 56342.132477551080228f, 56362.675618594614207f, 56383.220631706419226f, + 56403.767516545398394f, 56424.316272770607611f, 56444.866900041241024f, + 56465.419398016667401f, 56485.973766356393753f, 56506.530004720101715f, + 56527.088112767611165f, 56547.648090158902050f, 56568.209936554107117f, + 56588.773651613519178f, 56609.339234997583844f, 56629.906686366899521f, + 56650.476005382210133f, 56671.047191704419674f, 56691.620244994599489f, + 56712.195164913959161f, 56732.771951123868348f, 56753.350603285834950f, + 56773.931121061541489f, 56794.513504112823284f, 56815.097752101646620f, + 56835.683864690152404f, 56856.271841540627065f, 56876.861682315509825f, + 56897.453386677392700f, 56918.046954289027781f, 56938.642384813298122f, + 56959.239677913261403f, 56979.838833252120821f, 57000.439850493225094f, + 57021.042729300090286f, 57041.647469336370705f, 57062.254070265873452f, + 57082.862531752558425f, 57103.472853460552869f, 57124.085035054107720f, + 57144.699076197648537f, 57165.314976555739122f, 57185.932735793103348f, + 57206.552353574610606f, 57227.173829565275810f, 57247.797163430281216f, + 57268.422354834940052f, 57289.049403444732889f, 57309.678308925285819f, + 57330.309070942370454f, 57350.941689161911199f, 57371.576163249985257f, + 57392.212492872815346f, 57412.850677696784260f, 57433.490717388405756f, + 57454.132611614368216f, 57474.776360041490989f, 57495.421962336746219f, + 57516.069418167266122f, 57536.718727200313879f, 57557.369889103320020f, + 57578.022903543860593f, 57598.677770189642615f, 57619.334488708547724f, + 57639.993058768588526f, 57660.653480037937697f, 57681.315752184906160f, + 57701.979874877964903f, 57722.645847785730439f, 57743.313670576950244f, + 57763.983342920546420f, 57784.654864485572034f, 57805.328234941232949f, + 57826.003453956880549f, 57846.680521202026284f, 57867.359436346312577f, + 57888.040199059527367f, 57908.722809011633217f, 57929.407265872709104f, + 57950.093569313001353f, 57970.781719002894533f, 57991.471714612911455f, + 58012.163555813749554f, 58032.857242276222678f, 58053.552773671312025f, + 58074.250149670129758f, 58094.949369943948113f, 58115.650434164184844f, + 58136.353342002388672f, 58157.058093130275665f, 58177.764687219692860f, + 58198.473123942640086f, 58219.183402971255418f, 58239.895523977837001f, + 58260.609486634821224f, 58281.325290614775440f, 58302.042935590434354f, + 58322.762421234678186f, 58343.483747220510850f, 58364.206913221096329f, + 58384.931918909751403f, 58405.658763959923817f, 58426.387448045199562f, + 58447.117970839339250f, 58467.850332016212633f, 58488.584531249864085f, + 58509.320568214461673f, 58530.058442584333534f, 58550.798154033931496f, + 58571.539702237874735f, 58592.283086870906118f, 58613.028307607928582f, + 58633.775364123983309f, 58654.524256094249722f, 58675.274983194052766f, + 58696.027545098877454f, 58716.781941484325216f, 58737.538172026157554f, + 58758.296236400274211f, 58779.056134282727726f, 58799.817865349694330f, + 58820.581429277503048f, 58841.346825742642977f, 58862.114054421712353f, + 58882.883114991484035f, 58903.654007128847297f, 58924.426730510851485f, + 58945.201284814684186f, 58965.977669717663957f, 58986.755884897269425f, + 59007.535930031117459f, 59028.317804796948622f, 59049.101508872663544f, + 59069.887041936301102f, 59090.674403666045691f, 59111.463593740212673f, + 59132.254611837262928f, 59153.047457635802857f, 59173.842130814569828f, + 59194.638631052468554f, 59215.436958028505614f, 59236.237111421854934f, + 59257.039090911828680f, 59277.842896177877265f, 59298.648526899589342f, + 59319.455982756684534f, 59340.265263429049810f, 59361.076368596695829f, + 59381.889297939756943f, 59402.704051138542127f, 59423.520627873476769f, + 59444.339027825139055f, 59465.159250674230861f, 59485.981296101599582f, + 59506.805163788252685f, 59527.630853415314050f, 59548.458364664045803f, + 59569.287697215862863f, 59590.118850752318394f, 59610.951824955089251f, + 59631.786619506012357f, 59652.623234087048331f, 59673.461668380310584f, + 59694.301922068028944f, 59715.143994832593307f, 59735.987886356524541f, + 59756.833596322481753f, 59777.681124413255020f, 59798.530470311794488f, + 59819.381633701159444f, 59840.234614264569245f, 59861.089411685381492f, + 59881.946025647070201f, 59902.804455833269458f, 59923.664701927744318f, + 59944.526763614383526f, 59965.390640577243175f, 59986.256332500488497f, + 60007.123839068437519f, 60027.993159965539235f, 60048.864294876380882f, + 60069.737243485687941f, 60090.612005478324136f, 60111.488580539284158f, + 60132.366968353708216f, 60153.247168606867490f, 60174.129180984164122f, + 60195.013005171153054f, 60215.898640853512916f, 60236.786087717060582f, + 60257.675345447751170f, 60278.566413731670764f, 60299.459292255043692f, + 60320.353980704247078f, 60341.250478765759908f, 60362.148786126228515f, + 60383.048902472415648f, 60403.950827491236851f, 60424.854560869716806f, + 60445.760102295040269f, 60466.667451454515685f, 60487.576608035589743f, + 60508.487571725847374f, 60529.400342212997202f, 60550.314919184893370f, + 60571.231302329520986f, 60592.149491335003404f, 60613.069485889587668f, + 60633.991285681673617f, 60654.914890399784781f, 60675.840299732568383f, + 60696.767513368831715f, 60717.696530997483933f, 60738.627352307601541f, + 60759.559976988370181f, 60780.494404729128291f, 60801.430635219323449f, + 60822.368668148556026f, 60843.308503206564637f, 60864.250140083204315f, + 60885.193578468468331f, 60906.138818052495481f, 60927.085858525540971f, + 60948.034699578005529f, 60968.985340900420852f, 60989.937782183442323f, + 61010.892023117863573f, 61031.848063394616474f, 61052.805902704763866f, + 61073.765540739492280f, 61094.726977190133766f, 61115.690211748136790f, + 61136.655244105102611f, 61157.622073952741630f, 61178.590700982917042f, + 61199.561124887615733f, 61220.533345358948282f, 61241.507362089170783f, + 61262.483174770663027f, 61283.460783095943043f, 61304.440186757645279f, + 61325.421385448556975f, 61346.404378861581790f, 61367.389166689761623f, + 61388.375748626262066f, 61409.364124364386953f, 61430.354293597571086f, + 61451.346256019372959f, 61472.340011323496583f, 61493.335559203762386f, + 61514.332899354121764f, 61535.332031468671630f, 61556.332955241618038f, + 61577.335670367312559f, 61598.340176540237735f, 61619.346473454992520f, + 61640.354560806328664f, 61661.364438289099780f, 61682.376105598312279f, + 61703.389562429088983f, 61724.404808476690960f, 61745.421843436510244f, + 61766.440667004062561f, 61787.461278874987329f, 61808.483678745062207f, + 61829.507866310203099f, 61850.533841266435047f, 61871.561603309928614f, + 61892.591152136970777f, 61913.622487443986756f, 61934.655608927525464f, + 61955.690516284266778f, 61976.727209211021545f, 61997.765687404724304f, + 62018.805950562447833f, 62039.847998381381331f, 62060.891830558844958f, + 62081.937446792289848f, 62102.984846779298095f, 62124.034030217575491f, + 62145.084996804966067f, 62166.137746239415719f, 62187.192278219030413f, + 62208.248592442025256f, 62229.306688606739044f, 62250.366566411656095f, + 62271.428225555377139f, 62292.491665736626601f, 62313.556886654267146f, + 62334.623888007270580f, 62355.692669494761503f, 62376.763230815973657f, + 62397.835571670271747f, 62418.909691757144174f, 62439.985590776210302f, + 62461.063268427220464f, 62482.142724410048686f, 62503.223958424685406f, + 62524.306970171266585f, 62545.391759350030043f, 62566.478325661366398f, + 62587.566668805768131f, 62608.656788483880518f, 62629.748684396450699f, + 62650.842356244356779f, 62671.937803728622384f, 62693.035026550365728f, + 62714.134024410857819f, 62735.234797011478804f, 62756.337344053732522f, + 62777.441665239275608f, 62798.547760269852006f, 62819.655628847358457f, + 62840.765270673800842f, 62861.876685451323283f, 62882.989872882186319f, + 62904.104832668774179f, 62925.221564513602061f, 62946.340068119308853f, + 62967.460343188657134f, 62988.582389424525900f, 63009.706206529939664f, + 63030.831794208017527f, 63051.959152162038663f, 63073.088280095369555f, + 63094.219177711536759f, 63115.351844714154140f, 63136.486280806988361f, + 63157.622485693922499f, 63178.760459078956046f, 63199.900200666219462f, + 63221.041710159966897f, 63242.184987264568917f, 63263.330031684534333f, + 63284.476843124473817f, 63305.625421289143560f, 63326.775765883408894f, + 63347.927876612258842f, 63369.081753180813394f, 63390.237395294316229f, + 63411.394802658120170f, 63432.553974977716280f, 63453.714911958712037f, + 63474.877613306838612f, 63496.042078727943590f, 63517.208307927998248f, + 63538.376300613119383f, 63559.546056489503826f, 63580.717575263515755f, + 63601.890856641606661f, 63623.065900330373552f, 63644.242706036515301f, + 63665.421273466869025f, 63686.601602328380977f, 63707.783692328135658f, + 63728.967543173333979f, 63750.153154571278719f, 63771.340526229418174f, + 63792.529657855317055f, 63813.720549156649213f, 63834.913199841226742f, + 63856.107609616978152f, 63877.303778191941092f, 63898.501705274284177f, + 63919.701390572299715f, 63940.902833794403705f, 63962.106034649114008f, + 63983.310992845094006f, 64004.517708091108943f, 64025.726180096047756f, + 64046.936408568937622f, 64068.148393218900310f, 64089.362133755195828f, + 64110.577629887193325f, 64131.794881324392918f, 64153.013887776403863f, + 64174.234648952966381f, 64195.457164563937113f, 64216.681434319289110f, + 64237.907457929111843f, 64259.135235103625746f, 64280.364765553160396f, + 64301.596048988169059f, 64322.829085119235970f, 64344.063873657039949f, + 64365.300414312398061f, 64386.538706796251063f, 64407.778750819634297f, + 64429.020546093721350f, 64450.264092329809500f, 64471.509389239290613f, + 64492.756436533709348f, 64514.005233924704953f, 64535.255781124033092f, + 64556.508077843580395f, 64577.762123795357184f, 64599.017918691468367f, + 64620.275462244171649f, 64641.534754165804770f, 64662.795794168843713f, + 64684.058581965895428f, 64705.323117269661452f, 64726.589399792974291f, + 64747.857429248775588f, 64769.127205350137956f, 64790.398727810235869f, + 64811.671996342374769f, 64832.947010659969237f, 64854.223770476557547f, + 64875.502275505794387f, 64896.782525461450859f, 64918.064520057414484f, + 64939.348259007681918f, 64960.633742026388063f, 64981.920968827762408f, + 65003.209939126165409f, 65024.500652636066661f, 65045.793109072066727f, + 65067.087308148860757f, 65088.383249581282143f, 65109.680933084258868f, + 65130.980358372864430f, 65152.281525162259641f, 65173.584433167736279f, + 65194.889082104702538f, 65216.195471688683028f, 65237.503601635318773f, + 65258.813471660352661f, 65280.125081479665823f, 65301.438430809241254f, + 65322.753519365178363f, 65344.070346863707528f, 65365.388913021146436f, + 65386.709217553958297f, 65408.031260178700904f, 65429.355040612055745f, + 65450.680558570820722f, 65472.007813771910151f, 65493.336805932354764f, + 65514.667534769279882f, 65535.999999999956344f, 65557.334201341756852f, + 65578.670138512170524f, 65600.007811228788341f, 65621.347219209332252f, + 65642.688362171626068f, 65664.031239833639120f, 65685.375851913413499f, + 65706.722198129136814f, 65728.070278199083987f, 65749.420091841660906f, + 65770.771638775404426f, 65792.124918718938716f, 65813.479931391004357f, + 65834.836676510458346f, 65856.195153796303202f, 65877.555362967599649f, + 65898.917303743553930f, 65920.280975843488704f, 65941.646378986843047f, + 65963.013512893157895f, 65984.382377282076050f, 66005.752971873385832f, + 66027.125296386962873f, 66048.499350542799220f, 66069.875134061017889f, + 66091.252646661843755f, 66112.631888065618114f, 66134.012857992769568f, + 66155.395556163886795f, 66176.779982299631229f, 66198.166136120795272f, + 66219.554017348273192f, 66240.943625703104772f, 66262.334960906388005f, + 66283.728022679395508f, 66305.122810743443551f, 66326.519324820023030f, + 66347.917564630697598f, 66369.317529897161876f, 66390.719220341226901f, + 66412.122635684791021f, 66433.527775649883552f, 66454.934639958635671f, + 66476.343228333324078f, 66497.753540496283676f, 66519.165576169994893f, + 66540.579335077040014f, 66561.994816940117744f, 66583.412021482043201f, + 66604.830948425733368f, 66626.251597494221642f, 66647.673968410628731f, + 66669.098060898235417f, 66690.523874680380686f, 66711.951409480563598f, + 66733.380665022370522f, 66754.811641029475140f, 66776.244337225711206f, + 66797.678753334985231f, 66819.114889081320143f, 66840.552744188884390f, + 66861.992318381904624f, 66883.433611384738469f, 66904.876622921889066f, + 66926.321352717903210f, 66947.767800497502321f, 66969.215965985466028f, + 66990.665848906734027f, 67012.117448986304225f, 67033.570765949334600f, + 67055.025799521055887f, 67076.482549426815240f, 67097.941015392076224f, + 67119.401197142433375f, 67140.863094403553987f, 67162.326706901221769f, + 67183.792034361351398f, 67205.259076509959414f, 67226.727833073149668f, + 67248.198303777171532f, 67269.670488348347135f, 67291.144386513144127f, + 67312.619997998088365f, 67334.097322529880330f, 67355.576359835293260f, + 67377.057109641187708f, 67398.539571674569743f, 67420.023745662547299f, + 67441.509631332330173f, 67462.997228411230026f, 67484.486536626689485f, + 67505.977555706223939f, 67527.470285377494292f, 67548.964725368263316f, + 67570.460875406366540f, 67591.958735219799564f, 67613.458304536630749f, + 67634.959583085030317f, 67656.462570593328564f, 67677.967266789899440f, + 67699.473671403247863f, 67720.981784162024269f, 67742.491604794922750f, + 67764.003133030797471f, 67785.516368598575355f, 67807.031311227314291f, + 67828.547960646174033f, 67850.066316584401648f, 67871.586378771389718f, + 67893.108146936589037f, 67914.631620809610467f, 67936.156800120137632f, + 67957.683684597970569f, 67979.212273973011179f, 68000.742567975263228f, + 68022.274566334875999f, 68043.808268782056984f, 68065.343675047144643f, + 68086.880784860579297f, 68108.419597952917684f, 68129.960114054789301f, + 68151.502332896969165f, 68173.046254210319603f, 68194.591877725833911f, + 68216.139203174563590f, 68237.688230287705665f, 68259.238958796544466f, + 68280.791388432480744f, 68302.345518927031662f, 68323.901350011787144f, + 68345.458881418482633f, 68367.018112878911779f, 68388.579044125028304f, + 68410.141674888844136f, 68431.706004902502173f, 68453.272033898261725f, + 68474.839761608454864f, 68496.409187765544630f, 68517.980312102081371f, + 68539.553134350731852f, 68561.127654244279256f, 68582.703871515579522f, + 68604.281785897634109f, 68625.861397123502684f, 68647.442704926390434f, + 68669.025709039604408f, 68690.610409196524415f, 68712.196805130661232f, + 68733.784896575627499f, 68755.374683265123167f, 68776.966164932993706f, + 68798.559341313128243f, 68820.154212139590527f, 68841.750777146473411f, + 68863.349036068044370f, 68884.948988638629089f, 68906.550634592684219f, + 68928.153973664739169f, 68949.759005589439766f, 68971.365730101577356f, + 68992.974146935986937f, 69014.584255827634479f, 69036.196056511587813f, + 69057.809548723016633f, 69079.424732197207049f, 69101.041606669532484f, + 69122.660171875468222f, 69144.280427550605964f, 69165.902373430624721f, + 69187.526009251334472f, 69209.151334748617955f, 69230.778349658474326f, + 69252.407053716990049f, 69274.037446660411661f, 69295.669528225000249f, + 69317.303298147191526f, 69338.938756163493963f, 69360.575902010532445f, + 69382.214735425004619f, 69403.855256143753650f, 69425.497463903680909f, + 69447.141358441833290f, 69468.786939495330444f, 69490.434206801393884f, + 69512.083160097390646f, 69533.733799120716867f, 69555.386123608928756f, + 69577.040133299669833f, 69598.695827930685482f, 69620.353207239793846f, + 69642.012270964973141f, 69663.673018844259786f, 69685.335450615792070f, + 69706.999566017839243f, 69728.665364788743318f, 69750.332846666962723f, + 69772.002011391057749f, 69793.672858699690551f, 69815.345388331610593f, + 69837.019600025669206f, 69858.695493520848686f, 69880.373068556204089f, + 69902.052324870906887f, 69923.733262204215862f, 69945.415880295491661f, + 69967.100178884211346f, 69988.786157709939289f, 70010.473816512356279f, + 70032.163155031215865f, 70053.854173006402561f, 70075.546870177873643f, + 70097.241246285717352f, 70118.937301070109243f, 70140.635034271297627f, + 70162.334445629690890f, 70184.035534885741072f, 70205.738301780016627f, + 70227.442746053216979f, 70249.148867446099757f, 70270.856665699539008f, + 70292.566140554510639f, 70314.277291752106976f, 70335.990119033493102f, + 70357.704622139935964f, 70379.420800812818925f, 70401.138654793612659f, + 70422.858183823889703f, 70444.579387645339011f, 70466.302265999722295f, + 70488.026818628917681f, 70509.753045274876058f, 70531.480945679708384f, + 70553.210519585554721f, 70574.941766734700650f, 70596.674686869504512f, + 70618.409279732455616f, 70640.145545066101477f, 70661.883482613106025f, + 70683.623092116264161f, 70705.364373318414437f, 70727.107325962526374f, + 70748.851949791671359f, 70770.598244549008086f, 70792.346209977782564f, + 70814.095845821371768f, 70835.847151823225431f, 70857.600127726895153f, + 70879.354773276034393f, 70901.111088214413030f, 70922.869072285859147f, + 70944.628725234331796f, 70966.390046803877340f, 70988.153036738629453f, + 71009.917694782852777f, 71031.684020680884714f, 71053.452014177149977f, + 71075.221675016204244f, 71096.993002942661406f, 71118.765997701266315f, + 71140.540659036851139f, 71162.316986694335355f, 71184.094980418740306f, + 71205.874639955218299f, 71227.655965048950748f, 71249.438955445293686f, + 71271.223610889632255f, 71293.009931127482560f, 71314.797915904477122f, + 71336.587564966306672f, 71358.378878058763803f, 71380.171854927772074f, + 71401.966495319313253f, 71423.762798979485524f, 71445.560765654488932f, + 71467.360395090596285f, 71489.161687034211354f, 71510.964641231810674f, + 71532.769257429972640f, 71554.575535375362961f, 71576.383474814749206f, + 71598.193075495029916f, 71620.004337163132732f, 71641.817259566145367f, + 71663.631842451213743f, 71685.448085565600195f, 71707.265988656639820f, + 71729.085551471784129f, 71750.906773758586496f, 71772.729655264673056f, + 71794.554195737771806f, 71816.380394925712608f, 71838.208252576441737f, + 71860.037768437963678f, 71881.868942258384777f, 71903.701773785942351f, + 71925.536262768931920f, 71947.372408955750871f, 71969.210212094898452f, + 71991.049671934975777f, 72012.890788224685821f, 72034.733560712789767f, + 72056.577989148165216f, 72078.424073279820732f, 72100.271812856793986f, + 72122.121207628253615f, 72143.972257343470119f, 72165.824961751801311f, + 72187.679320602692314f, 72209.535333645690116f, 72231.393000630429015f, + 72253.252321306645172f, 72275.113295424176613f, 72296.975922732948675f, + 72318.840202982959454f, 72340.706135924338014f, 72362.573721307271626f, + 72384.442958882093080f, 72406.313848399178823f, 72428.186389609036269f, + 72450.060582262216485f, 72471.936426109430613f, 72493.813920901433448f, + 72515.693066389096202f, 72537.573862323391950f, 72559.456308455351973f, + 72581.340404536138522f, 72603.226150316986605f, 72625.113545549247647f, + 72647.002589984331280f, 72668.893283373763552f, 72690.785625469172373f, + 72712.679616022272967f, 72734.575254784853314f, 72756.472541508817812f, + 72778.371475946143619f, 72800.272057848938857f, 72822.174286969355308f, + 72844.078163059690269f, 72865.983685872284696f, 72887.890855159595958f, + 72909.799670674183290f, 72931.710132168693235f, 72953.622239395845099f, + 72975.535992108474602f, 72997.451390059519326f, 73019.368433001960511f, + 73041.287120688924915f, 73063.207452873612056f, 73085.129429309294210f, + 73107.053049749389174f, 73128.978313947343850f, 73150.905221656736103f, + 73172.833772631216561f, 73194.763966624566820f, 73216.695803390612127f, + 73238.629282683279598f, 73260.564404256627313f, 73282.501167864757008f, + 73304.439573261901387f, 73326.379620202336810f, 73348.321308440485154f, + 73370.264637730841059f, 73392.209607827957370f, 73414.156218486532453f, + 73436.104469461322878f, 73458.054360507172532f, 73480.005891379056266f, + 73501.959061831992585f, 73523.913871621116414f, 73545.870320501664537f, + 73567.828408228931949f, 73589.788134558330057f, 73611.749499245357583f, + 73633.712502045615111f, 73655.677142714746878f, 73677.643421008557198f, + 73699.611336682879482f, 73721.580889493692666f, 73743.552079197019339f, + 73765.524905548998504f, 73787.499368305856478f, 73809.475467223906890f, + 73831.453202059550676f, 73853.432572569290642f, 73875.413578509716899f, + 73897.396219637506874f, 73919.380495709410752f, 73941.366406482309685f, + 73963.353951713143033f, 73985.343131158952019f, 74007.333944576865179f, + 74029.326391724112909f, 74051.320472357969265f, 74073.316186235882924f, + 74095.313533115302562f, 74117.312512753836927f, 74139.313124909138423f, + 74161.315369338975870f, 74183.319245801190846f, 74205.324754053726792f, + 74227.331893854629016f, 74249.340664961986477f, 74271.351067134033656f, + 74293.363100129048689f, 74315.376763705440680f, 74337.392057621662389f, + 74359.408981636297540f, 74381.427535508002620f, 74403.447718995506875f, + 74425.469531857670518f, 74447.492973853382864f, 74469.518044741693302f, + 74491.544744281680323f, 74513.573072232538834f, 74535.603028353551053f, + 74557.634612404086511f, 74579.667824143602047f, 74601.702663331641816f, + 74623.739129727837280f, 74645.777223091936321f, 74667.816943183715921f, + 74689.858289763113135f, 74711.901262590094120f, 74733.945861424741452f, + 74755.992086027225014f, 74778.039936157802003f, 74800.089411576816929f, + 74822.140512044701609f, 74844.193237321960623f, 74866.247587169229519f, + 74888.303561347187497f, 74910.361159616630175f, 74932.420381738411379f, + 74954.481227473501349f, 74976.543696582972188f, 74998.607788827925106f, + 75020.673503969606827f, 75042.740841769322287f, 75064.809801988463732f, + 75086.880384388539824f, 75108.952588731102878f, 75131.026414777836180f, + 75153.101862290466670f, 75175.178931030852254f, 75197.257620760923601f, + 75219.337931242669583f, 75241.419862238224596f, 75263.503413509737584f, + 75285.588584819503012f, 75307.675375929873553f, 75329.763786603318295f, + 75351.853816602364532f, 75373.945465689612320f, 75396.038733627807233f, + 75418.133620179723948f, 75440.230125108253560f, 75462.328248176359921f, + 75484.427989147108747f, 75506.529347783653066f, 75528.632323849189561f, + 75550.736917107074987f, 75572.843127320695203f, 75594.950954253537930f, + 75617.060397669192753f, 75639.171457331307465f, 75661.284133003646275f, + 75683.398424450031598f, 75705.514331434402266f, 75727.631853720740764f, + 75749.750991073175101f, 75771.871743255862384f, 75793.994110033076140f, + 75816.118091169177205f, 75838.243686428584624f, 75860.370895575848408f, + 75882.499718375562225f, 75904.630154592421604f, 75926.762203991223942f, + 75948.895866336824838f, 75971.031141394181759f, 75993.168028928324929f, + 76015.306528704400989f, 76037.446640487600234f, 76059.588364043214824f, + 76081.731699136653333f, 76103.876645533353440f, 76126.023202998883789f, + 76148.171371298871236f, 76170.321150199044496f, 76192.472539465205045f, + 76214.625538863256224f, 76236.780148159174132f, 76258.936367119007627f, + 76281.094195508921985f, 76303.253633095140685f, 76325.414679643974523f, + 76347.577334921850706f, 76369.741598695225548f, 76391.907470730686327f, + 76414.074950794878532f, 76436.244038654564065f, 76458.414734076548484f, + 76480.587036827753764f, 76502.760946675174637f, 76524.936463385893148f, + 76547.113586727049551f, 76569.292316465915064f, 76591.472652369819116f, + 76613.654594206163893f, 76635.838141742467997f, 76658.023294746308238f, + 76680.210052985348739f, 76702.398416227340931f, 76724.588384240138112f, + 76746.779956791637233f, 76768.973133649866213f, 76791.167914582896628f, + 76813.364299358901917f, 76835.562287746157381f, 76857.761879512967425f, + 76879.963074427796528f, 76902.165872259109165f, 76924.370272775529884f, + 76946.576275745726889f, 76968.783880938441143f, 76990.993088122515474f, + 77013.203897066894569f, 77035.416307540566777f, 77057.630319312622305f, + 77079.845932152238674f, 77102.063145828695269f, 77124.281960111300577f, + 77146.502374769479502f, 77168.724389572758810f, 77190.948004290723475f, + 77213.173218693031231f, 77235.400032549441676f, 77257.628445629801718f, + 77279.858457704031025f, 77302.090068542122026f, 77324.323277914169012f, + 77346.558085590339033f, 77368.794491340886452f, 77391.032494936138391f, + 77413.272096146523836f, 77435.513294742529979f, 77457.756090494731325f, + 77480.000483173804241f, 77502.246472550497856f, 77524.494058395634056f, + 77546.743240480107488f, 77568.994018574943766f, 77591.246392451197607f, + 77613.500361880025594f, 77635.755926632657065f, 77658.013086480437778f, + 77680.271841194757144f, 77702.532190547091886f, 77724.794134309020592f, + 77747.057672252194607f, 77769.322804148323485f, 77791.589529769247747f, + 77813.857848886837019f, 77836.127761273062788f, 77858.399266699998407f, + 77880.672364939789986f, 77902.947055764627294f, 77925.223338946831063f, + 77947.501214258780237f, 77969.780681472926517f, 77992.061740361838019f, + 78014.344390698126517f, 78036.628632254491094f, 78058.914464803747251f, + 78081.201888118725037f, 78103.490901972414576f, 78125.781506137820543f, + 78148.073700388064026f, 78170.367484496338875f, 78192.662858235926251f, + 78214.959821380165522f, 78237.258373702497920f, 78259.558514976451988f, + 78281.860244975614478f, 78304.163563473659451f, 78326.468470244362834f, + 78348.774965061529656f, 78371.083047699125018f, 78393.392717931099469f, + 78415.703975531578180f, 78438.016820274700876f, 78460.331251934694592f, + 78482.647270285902778f, 78504.964875102727092f, 78527.284066159627400f, + 78549.604843231194536f, 78571.927206092048436f, 78594.251154516910901f, + 78616.576688280605595f, 78638.903807157985284f, 78661.232510924033704f, + 78683.562799353778246f, 78705.894672222348163f, 78728.228129304945469f, + 78750.563170376859489f, 78772.899795213423204f, 78795.238003590100561f, + 78817.577795282399165f, 78839.919170065928483f, 78862.262127716356190f, + 78884.606668009451823f, 78906.952790721043129f, 78929.300495627045166f, + 78951.649782503460301f, 78974.000651126378216f, 78996.353101271932246f, + 79018.707132716357592f, 79041.062745235976763f, 79063.419938607185031f, + 79085.778712606435874f, 79108.139067010284634f, 79130.501001595388516f, + 79152.864516138419276f, 79175.229610416179639f, 79197.596284205530537f, + 79219.964537283420213f, 79242.334369426869671f, 79264.705780412987224f, + 79287.078770018953946f, 79309.453338022009120f, 79331.829484199508443f, + 79354.207208328865818f, 79376.586510187582462f, 79398.967389553217799f, + 79421.349846203433117f, 79443.733879915947909f, 79466.119490468583535f, + 79488.506677639219561f, 79510.895441205822863f, 79533.285780946433078f, + 79555.677696639162605f, 79578.071188062225701f, 79600.466254993894836f, + 79622.862897212515236f, 79645.261114496548544f, 79667.660906624470954f, + 79690.062273374875076f, 79712.465214526455384f, 79734.869729857935454f, + 79757.275819148126175f, 79779.683482175954850f, 79802.092718720377889f, + 79824.503528560453560f, 79846.915911475327448f, 79869.329867244188790f, + 79891.745395646343241f, 79914.162496461154660f, 79936.581169468045118f, + 79959.001414446553099f, 79981.423231176260742f, 80003.846619436852052f, + 80026.271579008083791f, 80048.698109669770929f, 80071.126211201830301f, + 80093.555883384236949f, 80115.987125997053226f, 80138.419938820414245f, + 80160.854321634527878f, 80183.290274219689309f, 80205.727796356281033f, + 80228.166887824714649f, 80250.607548405532725f, 80273.049777879336034f, + 80295.493576026798110f, 80317.938942628650693f, 80340.385877465727390f, + 80362.834380318949115f, 80385.284450969280442f, 80407.736089197787805f, + 80430.189294785595848f, 80452.644067513916525f, 80475.100407164034550f, + 80497.558313517321949f, 80520.017786355208955f, 80542.478825459213112f, + 80564.941430610924726f, 80587.405601592006860f, 80609.871338184195338f, + 80632.338640169327846f, 80654.807507329300279f, 80677.277939446066739f, + 80699.749936301683192f, 80722.223497678278363f, 80744.698623358039185f, + 80767.175313123239903f, 80789.653566756242071f, 80812.133384039465454f, + 80834.614764755402575f, 80857.097708686647820f, 80879.582215615853784f, + 80902.068285325731267f, 80924.555917599092936f, 80947.045112218824215f, + 80969.535868967883289f, 80992.028187629271997f, 81014.522067986123147f, + 81037.017509821613203f, 81059.514512919005938f, 81082.013077061608783f, + 81104.513202032831032f, 81127.014887616183842f, 81149.518133595192921f, + 81172.022939753500395f, 81194.529305874806596f, 81217.037231742899166f, + 81239.546717141638510f, 81262.057761854957789f, 81284.570365666848375f, + 81307.084528361403500f, 81329.600249722774606f, 81352.117529535185895f, + 81374.636367582948878f, 81397.156763650447829f, 81419.678717522125226f, + 81442.202228982510860f, 81464.727297816221835f, 81487.253923807933461f, + 81509.782106742379256f, 81532.311846404394601f, 81554.843142578902189f, + 81577.375995050839265f, 81599.910403605274041f, 81622.446368027332937f, + 81644.983888102215133f, 81667.522963615178014f, 81690.063594351580832f, + 81712.605780096841045f, 81735.149520636448869f, 81757.694815755967284f, + 81780.241665241046576f, 81802.790068877409794f, 81825.340026450823643f, + 81847.891537747171242f, 81870.444602552379365f, 81892.999220652476652f, + 81915.555391833506292f, 81938.113115881671547f, 81960.672392583175679f, + 81983.233221724338364f, 82005.795603091537487f, 82028.359536471223691f, + 82050.925021649905830f, 82073.492058414209168f, 82096.060646550788078f, + 82118.630785846398794f, 82141.202476087841205f, 82163.775717062031617f, + 82186.350508555929991f, 82208.926850356569048f, 82231.504742251054267f, + 82254.084184026578441f, 82276.665175470392569f, 82299.247716369849513f, + 82321.831806512316689f, 82344.417445685307030f, 82367.004633676348021f, + 82389.593370273054461f, 82412.183655263143010f, 82434.775488434373983f, + 82457.368869574595010f, 82479.963798471697373f, 82502.560274913688772f, + 82525.158298688606010f, 82547.757869584602304f, 82570.358987389859976f, + 82592.961651892677764f, 82615.565862881398061f, 82638.171620144421468f, + 82660.778923470264999f, 82683.387772647474776f, 82705.998167464713333f, + 82728.610107710657758f, 82751.223593174116104f, 82773.838623643940082f, + 82796.455198909039609f, 82819.073318758441019f, 82841.692982981185196f, + 82864.314191366429441f, 82886.936943703374709f, 82909.561239781323820f, + 82932.187079389637802f, 82954.814462317735888f, 82977.443388355124625f, + 83000.073857291368768f, 83022.705868916120380f, 83045.339423019104288f, + 83067.974519390088972f, 83090.611157818959327f, 83113.249338095629355f, + 83135.889060010100366f, 83158.530323352460982f, 83181.173127912858035f, + 83203.817473481496563f, 83226.463359848668915f, 83249.110786804740201f, + 83271.759754140133737f, 83294.410261645374703f, 83317.062309111002833f, + 83339.715896327703376f, 83362.371023086161586f, 83385.027689177164575f, + 83407.685894391586771f, 83430.345638520360808f, 83453.006921354477527f, + 83475.669742685000529f, 83498.334102303095278f, 83520.999999999941792f, + 83543.667435566865606f, 83566.336408795192256f, 83589.006919476349140f, + 83611.678967401850969f, 83634.352552363241557f, 83657.027674152166583f, + 83679.704332560359035f, 83702.382527379551902f, 83725.062258401638246f, + 83747.743525418511126f, 83770.426328222180018f, 83793.110666604683502f, + 83815.796540358162019f, 83838.483949274828774f, 83861.172893146940623f, + 83883.863371766841738f, 83906.555384926963598f, 83929.248932419752236f, + 83951.944014037799207f, 83974.640629573696060f, 83997.338778820150765f, + 84020.038461569929495f, 84042.739677615856635f, 84065.442426750829327f, + 84088.146708767846576f, 84110.852523459921940f, 84133.559870620170841f, + 84156.268750041796011f, 84178.979161518029287f, 84201.691104842204368f, + 84224.404579807713162f, 84247.119586208005785f, 84269.836123836619663f, + 84292.554192487150431f, 84315.273791953281034f, 84337.994922028738074f, + 84360.717582507335464f, 84383.441773182945326f, 84406.167493849512539f, + 84428.894744301069295f, 84451.623524331691442f, 84474.353833735542139f, + 84497.085672306828201f, 84519.819039839872858f, 84542.553936128999339f, + 84565.290360968676396f, 84588.028314153401880f, 84610.767795477717300f, + 84633.508804736295133f, 84656.251341723822406f, 84678.995406235073460f, + 84701.740998064909945f, 84724.488117008251720f, 84747.236762860062299f, + 84769.986935415407061f, 84792.738634469409590f, 84815.491859817251679f, + 84838.246611254187883f, 84861.002888575560064f, 84883.760691576768295f, + 84906.520020053256303f, 84929.280873800569680f, 84952.043252614312223f, + 84974.807156290145940f, 84997.572584623805596f, 85020.339537411113270f, + 85043.108014447949245f, 85065.878015530237462f, 85088.649540453989175f, + 85111.422589015302947f, 85134.197161010320997f, 85156.973256235243753f, + 85179.750874486373505f, 85202.530015560070751f, 85225.310679252739646f, + 85248.092865360857104f, 85270.876573681016453f, 85293.661804009811021f, + 85316.448556143950555f, 85339.236829880188452f, 85362.026625015350874f, + 85384.817941346351290f, 85407.610778670132277f, 85430.405136783723719f, + 85453.201015484257368f, 85475.998414568864973f, 85498.797333834794699f, + 85521.597773079352919f, 85544.399732099904213f, 85567.203210693885922f, + 85590.008208658808144f, 85612.814725792239187f, 85635.622761891820119f, + 85658.432316755264765f, 85681.243390180330607f, 85704.055981964876992f, + 85726.870091906806920f, 85749.685719804081600f, 85772.502865454764105f, + 85795.321528656961164f, 85818.141709208852262f, 85840.963406908675097f, + 85863.786621554740123f, 85886.611352945445105f, 85909.437600879216916f, + 85932.265365154569736f, 85955.094645570090506f, 85977.925441924409824f, + 86000.757754016274703f, 86023.591581644432154f, 86046.426924607745605f, + 86069.263782705122139f, 86092.102155735556153f, 86114.942043498071143f, + 86137.783445791807026f, 86160.626362415918265f, 86183.470793169675744f, + 86206.316737852379447f, 86229.164196263402118f, 86252.013168202203815f, + 86274.863653468302800f, 86297.715651861260994f, 86320.569163180727628f, + 86343.424187226424692f, 86366.280723798117833f, 86389.138772695674561f, + 86411.998333718976937f, 86434.859406668008887f, 86457.721991342827096f, + 86480.586087543531903f, 86503.451695070296410f, 86526.318813723351923f, + 86549.187443303031614f, 86572.057583609683206f, 86594.929234443770838f, + 86617.802395605773199f, 86640.677066896270844f, 86663.553248115902534f, + 86686.430939065379789f, 86709.310139545443235f, 86732.190849356964463f, + 86755.073068300800514f, 86777.956796177953947f, 86800.842032789441873f, + 86823.728777936354163f, 86846.617031419853447f, 86869.506793041175115f, + 86892.398062601612764f, 86915.290839902518201f, 86938.185124745315989f, + 86961.080916931488900f, 86983.978216262607020f, 87006.877022540269536f, + 87029.777335566177499f, 87052.679155142090167f, 87075.582481069795904f, + 87098.487313151184935f, 87121.393651188220247f, 87144.301494982893928f, + 87167.210844337285380f, 87190.121699053532211f, 87213.034058933844790f, + 87235.947923780506244f, 87258.863293395828805f, 87281.780167582241120f, + 87304.698546142171836f, 87327.618428878180566f, 87350.539815592856030f, + 87373.462706088845152f, 87396.387100168896723f, 87419.312997635774082f, + 87442.240398292356986f, 87465.169301941539743f, 87488.099708386318525f, + 87511.031617429733160f, 87533.965028874896234f, 87556.899942525007646f, + 87579.836358183281845f, 87602.774275653020595f, 87625.713694737612968f, + 87648.654615240491694f, 87671.597036965147709f, 87694.540959715144709f, + 87717.486383294104598f, 87740.433307505736593f, 87763.381732153779012f, + 87786.331657042057486f, 87809.283081974455854f, 87832.236006754916161f, + 87855.190431187453214f, 87878.146355076154578f, 87901.103778225151473f, + 87924.062700438633328f, 87947.023121520891436f, 87969.985041276246193f, + 87992.948459509105305f, 88015.913376023905585f, 88038.879790625171154f, + 88061.847703117513447f, 88084.817113305573002f, 88107.788020994048566f, + 88130.760425987726194f, 88153.734328091464704f, 88176.709727110137464f, + 88199.686622848748812f, 88222.665015112303081f, 88245.644903705906472f, + 88268.626288434708840f, 88291.609169103947352f, 88314.593545518902829f, + 88337.579417484914302f, 88360.566784807408112f, 88383.555647291854257f, + 88406.546004743795493f, 88429.537856968818232f, 88452.531203772610752f, + 88475.526044960890431f, 88498.522380339447409f, 88521.520209714130033f, + 88544.519532890873961f, 88567.520349675658508f, 88590.522659874506644f, + 88613.526463293543202f, 88636.531759738922119f, 88659.538549016899196f, + 88682.546830933744786f, 88705.556605295845657f, 88728.567871909588575f, + 88751.580630581491278f, 88774.594881118071498f, 88797.610623325963388f, + 88820.627857011830201f, 88843.646581982393400f, 88866.666798044461757f, + 88889.688505004887702f, 88912.711702670610975f, 88935.736390848600422f, + 88958.762569345897646f, 88981.790237969631562f, 89004.819396526960190f, + 89027.850044825114310f, 89050.882182671412011f, 89073.915809873200487f, + 89096.950926237885142f, 89119.987531572973239f, 89143.025625686001149f, + 89166.065208384563448f, 89189.106279476356576f, 89212.148838769106078f, + 89235.192886070581153f, 89258.238421188667417f, 89281.285443931265036f, + 89304.333954106376041f, 89327.383951522017014f, 89350.435435986306402f, + 89373.488407307406305f, 89396.542865293537034f, 89419.598809753006208f, + 89442.656240494165104f, 89465.715157325394102f, 89488.775560055219103f, + 89511.837448492136900f, 89534.900822444746154f, 89557.965681721732835f, + 89581.032026131812017f, 89604.099855483742431f, 89627.169169586399221f, + 89650.239968248672085f, 89673.312251279538032f, 89696.386018488017726f, + 89719.461269683204591f, 89742.538004674250260f, 89765.616223270364571f, + 89788.695925280830124f, 89811.777110514987726f, 89834.859778782207286f, + 89857.943929891975131f, 89881.029563653806690f, 89904.116679877261049f, + 89927.205278372013709f, 89950.295358947740169f, 89973.386921414217795f, + 89996.479965581267606f, 90019.574491258783382f, 90042.670498256688006f, + 90065.767986385020777f, 90088.866955453835544f, 90111.967405273258919f, + 90135.069335653475719f, 90158.172746404758072f, 90181.277637337407214f, + 90204.384008261797135f, 90227.491858988360036f, 90250.601189327586326f, + 90273.711999090039171f, 90296.824288086325396f, 90319.938056127139134f, + 90343.053303023189073f, 90366.170028585285763f, 90389.288232624297962f, + 90412.407914951138082f, 90435.529075376776746f, 90458.651713712257333f, + 90481.775829768681433f, 90504.901423357208841f, 90528.028494289057562f, + 90551.157042375503806f, 90574.287067427911097f, 90597.418569257642957f, + 90620.551547676193877f, 90643.686002495072898f, 90666.821933525847271f, + 90689.959340580186108f, 90713.098223469773075f, 90736.238582006364595f, + 90759.380416001804406f, 90782.523725267950795f, 90805.668509616763913f, + 90828.814768860233016f, 90851.962502810434671f, 90875.111711279459996f, + 90898.262394079531077f, 90921.414551022855449f, 90944.568181921742507f, + 90967.723286588559859f, 90990.879864835718763f, 91014.037916475717793f, + 91037.197441321070073f, 91060.358439184390591f, 91083.520909878337989f, + 91106.684853215629118f, 91129.850269009039039f, 91153.017157071401016f, + 91176.185517215621076f, 91199.355349254648900f, 91222.526653001492377f, + 91245.699428269246710f, 91268.873674871036201f, 91292.049392620057915f, + 91315.226581329552573f, 91338.405240812833654f, 91361.585370883287396f, + 91384.766971354343696f, 91407.950042039476102f, 91431.134582752245478f, + 91454.320593306256342f, 91477.508073515171418f, 91500.697023192726192f, + 91523.887442152685253f, 91547.079330208929605f, 91570.272687175325700f, + 91593.467512865856406f, 91616.663807094533695f, 91639.861569675442297f, + 91663.060800422725151f, 91686.261499150554300f, 91709.463665673218202f, + 91732.667299805019866f, 91755.872401360320509f, 91779.078970153568662f, + 91802.287005999256507f, 91825.496508711919887f, 91848.707478106167400f, + 91871.919913996680407f, 91895.133816198169370f, 91918.349184525417513f, + 91941.566018793280818f, 91964.784318816658924f, 91988.004084410495125f, + 92011.225315389820025f, 92034.448011569707887f, 92057.672172765291180f, + 92080.897798791746027f, 92104.124889464364969f, 92127.353444598411443f, + 92150.583464009279851f, 92173.814947512379149f, 92197.047894923220156f, + 92220.282306057313690f, 92243.518180730272434f, 92266.755518757752725f, + 92289.994319955469109f, 92313.234584139194340f, 92336.476311124773929f, + 92359.719500728082494f, 92382.964152765067411f, 92406.210267051748815f, + 92429.457843404161395f, 92452.706881638470804f, 92475.957381570813595f, + 92499.209343017442734f, 92522.462765794669394f, 92545.717649718819303f, + 92568.973994606305496f, 92592.231800273613771f, 92615.491066537259030f, + 92638.751793213828932f, 92662.013980119940243f, 92685.277627072326140f, + 92708.542733887719805f, 92731.809300382956280f, 92755.077326374870609f, + 92778.346811680414248f, 92801.617756116582314f, 92824.890159500384470f, + 92848.164021648946800f, 92871.439342379424488f, 92894.716121509016375f, + 92917.994358855023165f, 92941.274054234745563f, 92964.555207465571584f, + 92987.837818364962004f, 93011.121886750406702f, 93034.407412439468317f, + 93057.694395249767695f, 93080.982834998954786f, 93104.272731504766853f, + 93127.564084584999364f, 93150.856894057491445f, 93174.151159740140429f, + 93197.446881450916408f, 93220.744059007804026f, 93244.042692228889791f, + 93267.342780932303867f, 93290.644324936234625f, 93313.947324058914091f, + 93337.251778118632501f, 93360.557686933767400f, 93383.865050322696334f, + 93407.173868103927816f, 93430.484140095941257f, 93453.795866117361584f, + 93477.109045986799174f, 93500.423679522951716f, 93523.739766544560553f, + 93547.057306870454340f, 93570.376300319490838f, 93593.696746710571460f, + 93617.018645862699486f, 93640.341997594892746f, 93663.666801726227277f, + 93686.993058075880981f, 93710.320766463031759f, 93733.649926706930273f, + 93756.980538626914495f, 93780.312602042336948f, 93803.646116772637470f, + 93826.981082637284999f, 93850.317499455835787f, 93873.655367047860636f, + 93896.994685233032214f, 93920.335453831037739f, 93943.677672661666293f, + 93967.021341544706956f, 93990.366460300050676f, 94013.713028747632052f, + 94037.061046707429341f, 94060.410513999493560f, 94083.761430443919380f, + 94107.113795860845130f, 94130.467610070511000f, 94153.822872893157182f, + 94177.179584149111179f, 94200.537743658758700f, 94223.897351242529112f, + 94247.258406720909989f, 94270.620909914432559f, 94293.984860643729917f, + 94317.350258729420602f, 94340.717103992239572f, 94364.085396252936334f, + 94387.455135332347709f, 94410.826321051339619f, 94434.198953230850748f, + 94457.573031691877986f, 94480.948556255447329f, 94504.325526742657530f, + 94527.703942974680103f, 94551.083804772715666f, 94574.465111958023044f, + 94597.847864351933822f, 94621.232061775823240f, 94644.617704051095643f, + 94668.004790999271790f, 94691.393322441872442f, 94714.783298200505669f, + 94738.174718096794095f, 94761.567581952476758f, 94784.961889589307248f, + 94808.357640829097363f, 94831.754835493702558f, 94855.153473405065597f, + 94878.553554385172902f, 94901.955078256054549f, 94925.358044839784270f, + 94948.762453958523110f, 94972.168305434475769f, 94995.575599089890602f, + 95018.984334747074172f, 95042.394512228391250f, 95065.806131356264814f, + 95089.219191953176050f, 95112.633693841635250f, 95136.049636844240013f, + 95159.467020783617045f, 95182.885845482465811f, 95206.306110763529432f, + 95229.727816449609236f, 95253.150962363564759f, 95276.575548328313744f, + 95300.001574166803039f, 95323.429039702052251f, 95346.857944757153746f, + 95370.288289155214443f, 95393.720072719428572f, 95417.153295273019467f, + 95440.587956639297772f, 95464.024056641588686f, 95487.461595103304717f, + 95510.900571847902029f, 95534.340986698865891f, 95557.782839479783433f, + 95581.226130014256341f, 95604.670858125959057f, 95628.117023638595128f, + 95651.564626375984517f, 95675.013666161918081f, 95698.464142820303096f, + 95721.916056175075937f, 95745.369406050231191f, 95768.824192269807099f, + 95792.280414657914662f, 95815.738073038708535f, 95839.197167236387031f, + 95862.657697075221222f, 95886.119662379540387f, 95909.583062973688357f, + 95933.047898682110826f, 95956.514169329268043f, 95979.981874739707564f, + 96003.451014738006052f, 96026.921589148798375f, 96050.393597796792164f, + 96073.867040506724152f, 96097.341917103374726f, 96120.818227411626140f, + 96144.295971256375196f, 96167.775148462576908f, 96191.255758855244494f, + 96214.737802259449381f, 96238.221278500306653f, 96261.706187402989599f, + 96285.192528792715166f, 96308.680302494787611f, 96332.169508334525744f, + 96355.660146137321135f, 96379.152215728609008f, 96402.645716933868243f, + 96426.140649578665034f, 96449.637013488594675f, 96473.134808489310672f, + 96496.634034406510182f, 96520.134691065963125f, 96543.636778293468524f, + 96567.140295914883609f, 96590.645243756152922f, 96614.151621643221006f, + 96637.659429402134265f, 96661.168666858953657f, 96684.679333839798346f, + 96708.191430170874810f, 96731.704955678389524f, 96755.219910188665381f, + 96778.736293528010719f, 96802.254105522835744f, 96825.773345999579760f, + 96849.294014784740284f, 96872.816111704873038f, 96896.339636586577399f, + 96919.864589256510953f, 96943.390969541389495f, 96966.918777267957921f, + 96990.448012263048440f, 97013.978674353522365f, 97037.510763366284664f, + 97061.044279128327616f, 97084.579221466672607f, 97108.115590208384674f, + 97131.653385180587065f, 97155.192606210490339f, 97178.733253125290503f, + 97202.275325752299977f, 97225.818823918860289f, 97249.363747452342068f, + 97272.910096180188702f, 97296.457869929916342f, 97320.007068529041135f, + 97343.557691805195645f, 97367.109739586012438f, 97390.663211699196836f, + 97414.218107972497819f, 97437.774428233737126f, 97461.332172310765600f, + 97484.891340031506843f, 97508.451931223899010f, 97532.013945715982118f, + 97555.577383335810737f, 97579.142243911512196f, 97602.708527271257481f, + 97626.276233243261231f, 97649.845361655810848f, 97673.415912337222835f, + 97696.987885115886456f, 97720.561279820205527f, 97744.136096278700279f, + 97767.712334319876391f, 97791.289993772341404f, 97814.869074464702862f, + 97838.449576225684723f, 97862.031498883996392f, 97885.614842268449138f, + 97909.199606207883335f, 97932.785790531183011f, 97956.373395067319507f, + 97979.962419645264163f, 98003.552864094075630f, 98027.144728242856218f, + 98050.738011920766439f, 98074.332714956995915f, 98097.928837180807022f, + 98121.526378421505797f, 98145.125338508456480f, 98168.725717271066969f, + 98192.327514538774267f, 98215.930730141131789f, 98239.535363907663850f, + 98263.141415668011177f, 98286.748885251814499f, 98310.357772488816408f, + 98333.968077208759496f, 98357.579799241488217f, 98381.192938416847028f, + 98404.807494564782246f, 98428.423467515240191f, 98452.040857098269043f, + 98475.659663143916987f, 98499.279885482319514f, 98522.901523943655775f, + 98546.524578358163126f, 98570.149048556093476f, 98593.774934367786045f, + 98617.402235623623710f, 98641.030952154047554f, 98664.661083789513214f, + 98688.292630360563635f, 98711.925591697770869f, 98735.559967631794279f, + 98759.195757993293228f, 98782.832962613014388f, 98806.471581321733538f, + 98830.111613950284664f, 98853.753060329574510f, 98877.395920290509821f, + 98901.040193664099206f, 98924.685880281380378f, 98948.332979973420152f, + 98971.981492571387207f, 98995.631417906450224f, 99019.282755809850642f, + 99042.935506112873554f, 99066.589668646876817f, 99090.245243243232835f, + 99113.902229733401327f, 99137.560627948856563f, 99161.220437721145572f, + 99184.881658881859039f, 99208.544291262631305f, 99232.208334695169469f, + 99255.873789011209738f, 99279.540654042546521f, 99303.208929621032439f, + 99326.878615578520112f, 99350.549711746993125f, 99374.222217958435067f, + 99397.896134044887731f, 99421.571459838422015f, 99445.248195171210682f, + 99468.926339875441045f, 99492.605893783344072f, 99516.286856727208942f, + 99539.969228539397591f, 99563.653009052286507f, 99587.338198098324938f, + 99611.024795510005788f, 99634.712801119865617f, 99658.402214760499191f, + 99682.093036264544935f, 99705.785265464699478f, 99729.478902193688555f, + 99753.173946284325211f, 99776.870397569437046f, 99800.568255881909863f, + 99824.267521054687677f, 99847.968192920772708f, 99871.670271313181729f, + 99895.373756065004272f, 99919.078647009388078f, 99942.784943979524542f, + 99966.492646808634163f, 99990.201755330010201f, 100013.912269376989570f, + 100037.624188782952842f, 100061.337513381338795f, 100085.052243005629862f, + 100108.768377489352133f, 100132.485916666104458f, 100156.204860369500238f, + 100179.925208433225635f, 100203.646960691010463f, 100227.370116976642748f, + 100251.094677123939618f, 100274.820640966776409f, 100298.548008339086664f, + 100322.276779074833030f, 100346.006953008065466f, 100369.738529972833931f, + 100393.471509803275694f, 100417.205892333542579f, 100440.941677397888270f, + 100464.678864830551902f, 100488.417454465859919f, 100512.157446138196974f, + 100535.898839681962272f, 100559.641634931613225f, 100583.385831721694558f, + 100607.131429886736441f, 100630.878429261370911f, 100654.626829680244555f, + 100678.376630978091271f, 100702.127832989644958f, 100725.880435549712274f, + 100749.634438493158086f, 100773.389841654905467f, 100797.146644869862939f, + 100820.904847973069991f, 100844.664450799566112f, 100868.425453184434446f, + 100892.187854962845449f, 100915.951655969984131f, 100939.716856041093706f, + 100963.483455011461047f, 100987.251452716445783f, 101011.020848991422099f, + 101034.791643671822385f, 101058.563836593166343f, 101082.337427590944571f, + 101106.112416500778636f, 101129.888803158275550f, 101153.666587399115087f, + 101177.445769059049780f, 101201.226347973832162f, 101225.008323979287525f, + 101248.791696911299368f, 101272.576466605794849f, 101296.362632898730226f, + 101320.150195626119967f, 101343.939154624036746f, 101367.729509728596895f, + 101391.521260775960400f, 101415.314407602330903f, 101439.108950043970253f, + 101462.904887937198509f, 101486.702221118335729f, 101510.500949423818383f, + 101534.301072690082947f, 101558.102590753624099f, 101581.905503450980177f, + 101605.709810618762276f, 101629.515512093596044f, 101653.322607712179888f, + 101677.131097311255871f, 101700.940980727595161f, 101724.752257798041683f, + 101748.564928359468468f, 101772.378992248806753f, 101796.194449303031433f, + 101820.011299359161058f, 101843.829542254272383f, 101867.649177825485822f, + 101891.470205909965443f, 101915.292626344918972f, 101939.116438967626891f, + 101962.941643615369685f, 101986.768240125529701f, 102010.596228335489286f, + 102034.425608082718099f, 102058.256379204714904f, 102082.088541539007565f, + 102105.922094923196710f, 102129.757039194941171f, 102153.593374191914336f, + 102177.431099751847796f, 102201.270215712531353f, 102225.110721911798464f, + 102248.952618187526241f, 102272.795904377635452f, 102296.640580320090521f, + 102320.486645852928632f, 102344.334100814216072f, 102368.182945042048232f, + 102392.033178374607814f, 102415.884800650077523f, 102439.737811706727371f, + 102463.592211382871028f, 102487.447999516836717f, 102511.305175947039970f, + 102535.163740511896322f, 102559.023693049923168f, 102582.885033399652457f, + 102606.747761399674346f, 102630.611876888593542f, 102654.477379705116618f, + 102678.344269687950145f, 102702.212546675873455f, 102726.082210507709533f, + 102749.953261022310471f, 102773.825698058601120f, 102797.699521455535432f, + 102821.574731052125571f, 102845.451326687427354f, 102869.329308200511150f, + 102893.208675430563744f, 102917.089428216742817f, 102940.971566398307914f, + 102964.855089814547682f, 102988.739998304779874f, 103012.626291708395001f, + 103036.513969864812680f, 103060.403032613510732f, 103084.293479793996084f, + 103108.185311245848425f, 103132.078526808661991f, 103155.973126322118333f, + 103179.869109625899000f, 103203.766476559772855f, 103227.665226963523310f, + 103251.565360677006538f, 103275.466877540107816f, 103299.369777392756077f, + 103323.274060074953013f, 103347.179725426700315f, 103371.086773288101540f, + 103394.995203499245690f, 103418.905015900338185f, 103442.816210331569891f, + 103466.728786633189884f, 103490.642744645534549f, 103514.558084208940272f, + 103538.474805163801648f, 103562.392907350571477f, 103586.312390609731665f, + 103610.233254781836877f, 103634.155499707441777f, 103658.079125227188342f, + 103682.004131181762205f, 103705.930517411878100f, 103729.858283758294419f, + 103753.787430061827763f, 103777.717956163338386f, 103801.649861903715646f, + 103825.583147123936214f, 103849.517811664976762f, 103873.453855367901269f, + 103897.391278073759167f, 103921.330079623716301f, 103945.270259858938516f, + 103969.211818620664417f, 103993.154755750132608f, 104017.099071088698111f, + 104041.044764477701392f, 104064.991835758541129f, 104088.940284772688756f, + 104112.890111361630261f, 104136.841315366924391f, 104160.793896630144445f, + 104184.747854992951034f, 104208.703190296990215f, 104232.659902384009911f, + 104256.617991095772595f, 104280.577456274113501f, 104304.538297760867863f, + 104328.500515397972777f, 104352.464109027365339f, 104376.429078491040855f, + 104400.395423631052836f, 104424.363144289483898f, 104448.332240308460314f, + 104472.302711530195666f, 104496.274557796888985f, 104520.247778950812062f, + 104544.222374834280345f, 104568.198345289652934f, 104592.175690159361693f, + 104616.154409285823931f, 104640.134502511558821f, 104664.115969679100090f, + 104688.098810631025117f, 104712.083025209984044f, 104736.068613258641562f, + 104760.055574619720574f, 104784.043909136002185f, 104808.033616650267504f, + 104832.024697005414055f, 104856.017150044310256f, 104880.010975609911839f, + 104904.006173545218189f, 104928.002743693257798f, 104952.000685897131916f, + 104975.999999999927240f, 105000.000685844861437f, 105024.002743275108514f, + 105048.006172133958898f, 105072.010972264703014f, 105096.017143510704045f, + 105120.024685715339729f, 105144.033598722075112f, 105168.043882374360692f, + 105192.055536515748827f, 105216.068560989820980f, 105240.082955640173168f, + 105264.098720310474164f, 105288.115854844436399f, 105312.134359085815959f, + 105336.154232878398034f, 105360.175476066040574f, 105384.198088492616080f, + 105408.222070002055261f, 105432.247420438332483f, 105456.274139645465766f, + 105480.302227467531338f, 105504.331683748634532f, 105528.362508332909783f, + 105552.394701064578840f, 105576.428261787863448f, 105600.463190347058116f, + 105624.499486586486455f, 105648.537150350530283f, 105672.576181483600521f, + 105696.616579830166302f, 105720.658345234725857f, 105744.701477541835629f, + 105768.745976596095716f, 105792.791842242135317f, 105816.839074324641842f, + 105840.887672688346356f, 105864.937637178009027f, 105888.988967638462782f, + 105913.041663914555102f, 105937.095725851191673f, 105961.151153293321840f, + 105985.207946085953154f, 106009.266104074093164f, 106033.325627102836734f, + 106057.386515017293277f, 106081.448767662659520f, 106105.512384884117637f, + 106129.577366526951664f, 106153.643712436431088f, 106177.711422457912704f, + 106201.780496436796966f, 106225.850934218484326f, 106249.922735648477101f, + 106273.995900572277606f, 106298.070428835460916f, 106322.146320283616660f, + 106346.223574762407225f, 106370.302192117509549f, 106394.382172194687882f, + 106418.463514839691925f, 106442.546219898373238f, 106466.630287216583383f, + 106490.715716640246683f, 106514.802508015287458f, 106538.890661187746446f, + 106562.980176003635279f, 106587.071052309052902f, 106611.163289950112812f, + 106635.256888773015817f, 106659.351848623948172f, 106683.448169349183445f, + 106707.545850795024307f, 106731.644892807817087f, 106755.745295233951765f, + 106779.847057919861982f, 106803.950180712010479f, 106828.054663456932758f, + 106852.160506001178874f, 106876.267708191371639f, 106900.376269874133868f, + 106924.486190896190237f, 106948.597471104250872f, 106972.710110345113208f, + 106996.824108465589234f, 107020.939465312534594f, 107045.056180732877692f, + 107069.174254573561484f, 107093.293686681587133f, 107117.414476903970353f, + 107141.536625087814173f, 107165.660131080236170f, 107189.784994728397578f, + 107213.911215879517840f, 107238.038794380845502f, 107262.167730079672765f, + 107286.298022823335486f, 107310.429672459227731f, 107334.562678834758117f, + 107358.697041797408019f, 107382.832761194673367f, 107406.969836874122848f, + 107431.108268683354254f, 107455.248056469994481f, 107479.389200081714080f, + 107503.531699366270914f, 107527.675554171393742f, 107551.820764344927738f, + 107575.967329734688974f, 107600.115250188609934f, 107624.264525554608554f, + 107648.415155680660973f, 107672.567140414801543f, 107696.720479605079163f, + 107720.875173099630047f, 107745.031220746575855f, 107769.188622394140111f, + 107793.347377890531789f, 107817.507487084032618f, 107841.668949822982540f, + 107865.831765955721494f, 107889.995935330676730f, 107914.161457796290051f, + 107938.328333201046917f, 107962.496561393476441f, 107986.666142222165945f, + 108010.837075535717304f, 108035.009361182819703f, 108059.182999012147775f, + 108083.357988872448914f, 108107.534330612528720f, 108131.712024081207346f, + 108155.891069127348601f, 108180.071465599874500f, 108204.253213347750716f, + 108228.436312219957472f, 108252.620762065533199f, 108276.806562733574538f, + 108300.993714073207229f, 108325.182215933586122f, 108349.372068163938820f, + 108373.563270613492932f, 108397.755823131563375f, 108421.949725567465066f, + 108446.144977770600235f, 108470.341579590356559f, 108494.539530876223580f, + 108518.738831477690837f, 108542.939481244320632f, 108567.141480025660712f, + 108591.344827671389794f, 108615.549524031142937f, 108639.755568954642513f, + 108663.962962291654549f, 108688.171703891959623f, 108712.381793605411076f, + 108736.593231281876797f, 108760.806016771282884f, 108785.020149923584540f, + 108809.235630588809727f, 108833.452458616986405f, 108857.670633858215297f, + 108881.890156162611675f, 108906.111025380363571f, 108930.333241361688124f, + 108954.556803956817021f, 108978.781713016069261f, 109003.007968389763846f, + 109027.235569928307086f, 109051.464517482105293f, 109075.694810901622986f, + 109099.926450037368340f, 109124.159434739893186f, 109148.393764859763905f, + 109172.629440247634193f, 109196.866460754157742f, 109221.104826230061008f, + 109245.344536526099546f, 109269.585591493043466f, 109293.827990981750190f, + 109318.071734843106242f, 109342.316822928012698f, 109366.563255087428843f, + 109390.811031172372168f, 109415.060151033874718f, 109439.310614523012191f, + 109463.562421490933048f, 109487.815571788800298f, 109512.070065267806058f, + 109536.325901779200649f, 109560.583081174292602f, 109584.841603304404998f, + 109609.101468020904576f, 109633.362675175216282f, 109657.625224618779612f, + 109681.889116203092271f, 109706.154349779710174f, 109730.420925200203783f, + 109754.688842316187220f, 109778.958100979318260f, 109803.228701041298336f, + 109827.500642353887088f, 109851.773924768844154f, 109876.048548138001934f, + 109900.324512313236482f, 109924.601817146438407f, 109948.880462489571073f, + 109973.160448194597848f, 109997.441774113569409f, 110021.724440098550986f, + 110046.008446001636912f, 110070.293791675008833f, 110094.580476970819291f, + 110118.868501741337241f, 110143.157865838817088f, 110167.448569115571445f, + 110191.740611423971131f, 110216.033992616386968f, 110240.328712545277085f, + 110264.624771063114167f, 110288.922168022400001f, 110313.220903275709134f, + 110337.520976675645215f, 110361.822388074826449f, 110386.125137325943797f, + 110410.429224281717325f, 110434.734648794910754f, 110459.041410718316911f, + 110483.349509904786828f, 110507.658946207186091f, 110531.969719478467596f, + 110556.281829571569688f, 110580.595276339503471f, 110604.910059635323705f, + 110629.226179312085151f, 110653.543635222944431f, 110677.862427221058169f, + 110702.182555159626645f, 110726.504018891879241f, 110750.826818271132652f, + 110775.150953150703572f, 110799.476423383952351f, 110823.803228824282996f, + 110848.131369325143169f, 110872.460844740038738f, 110896.791654922475573f, + 110921.123799726032303f, 110945.457279004302109f, 110969.792092610965483f, + 110994.128240399673814f, 111018.465722224165802f, 111042.804537938223802f, + 111067.144687395659275f, 111091.486170450283680f, 111115.828986956024892f, + 111140.173136766796233f, 111164.518619736569235f, 111188.865435719329980f, + 111213.213584569166414f, 111237.563066140137380f, 111261.913880286389031f, + 111286.266026862067520f, 111310.619505721406313f, 111334.974316718638875f, + 111359.330459708042326f, 111383.687934543966549f, 111408.046741080775973f, + 111432.406879172864137f, 111456.768348674682784f, 111481.131149440727313f, + 111505.495281325507676f, 111529.860744183606585f, 111554.227537869635853f, + 111578.595662238207296f, 111602.965117144049145f, 111627.335902441845974f, + 111651.708017986398772f, 111676.081463632479426f, 111700.456239234961686f, + 111724.832344648704748f, 111749.209779728640569f, 111773.588544329744764f, + 111797.968638306992943f, 111822.350061515448033f, 111846.732813810187508f, + 111871.116895046332502f, 111895.502305079033249f, 111919.889043763498194f, + 111944.277110954950331f, 111968.666506508699968f, 111993.057230280042859f, + 112017.449282124347519f, 112041.842661896997015f, 112066.237369453432621f, + 112090.633404649124714f, 112115.030767339616432f, 112139.429457380421809f, + 112163.829474627156742f, 112188.230818935451680f, 112212.633490160966176f, + 112237.037488159432542f, 112261.442812786583090f, 112285.849463898222893f, + 112310.257441350171575f, 112334.666744998292415f, 112359.077374698492349f, + 112383.489330306721968f, 112407.902611678975518f, 112432.317218671261799f, + 112456.733151139647816f, 112481.150408940244233f, 112505.568991929190815f, + 112529.988899962656433f, 112554.410132896882715f, 112578.832690588111291f, + 112603.256572892627446f, 112627.681779666789225f, 112652.108310766983777f, + 112676.536166049583699f, 112700.965345371078001f, 112725.395848587941146f, + 112749.827675556720351f, 112774.260826133977389f, 112798.695300176303135f, + 112823.131097540375777f, 112847.568218082858948f, 112872.006661660489044f, + 112896.446428130031563f, 112920.887517348266556f, 112945.329929172075936f, + 112969.773663458312512f, 112994.218720063887304f, 113018.665098845784087f, + 113043.112799660986639f, 113067.561822366522392f, 113092.012166819476988f, + 113116.463832876950619f, 113140.916820396101684f, 113165.371129234132241f, + 113189.826759248244343f, 113214.283710295727360f, 113238.741982233870658f, + 113263.201574920021812f, 113287.662488211572054f, 113312.124721965927165f, + 113336.588276040551136f, 113361.053150292951614f, 113385.519344580665347f, + 113409.986858761243639f, 113434.455692692325101f, 113458.925846231548348f, + 113483.397319236610201f, 113507.870111565222032f, 113532.344223075167974f, + 113556.819653624246712f, 113581.296403070300585f, 113605.774471271215589f, + 113630.253858084906824f, 113654.734563369333046f, 113679.216586982496665f, + 113703.699928782414645f, 113728.184588627176709f, 113752.670566374872578f, + 113777.157861883679288f, 113801.646475011773873f, 113826.136405617362470f, + 113850.627653558738530f, 113875.120218694180949f, 113899.614100882041384f, + 113924.109299980700598f, 113948.605815848553902f, 113973.103648344069370f, + 113997.602797325744177f, 114022.103262652104604f, 114046.605044181706035f, + 114071.108141773176612f, 114095.612555285144481f, 114120.118284576281440f, + 114144.625329505332047f, 114169.133689931040863f, 114193.643365712196101f, + 114218.154356707644183f, 114242.666662776260637f, 114267.180283776935539f, + 114291.695219568617176f, 114316.211470010312041f, 114340.729034961026628f, + 114365.247914279825636f, 114389.768107825802872f, 114414.289615458095795f, + 114438.812437035885523f, 114463.336572418367723f, 114487.862021464796271f, + 114512.388784034483251f, 114536.916859986711643f, 114561.446249180866289f, + 114585.976951476361137f, 114610.508966732595582f, 114635.042294809085433f, + 114659.576935565317399f, 114684.112888860836392f, 114708.650154555260087f, + 114733.188732508177054f, 114757.728622579277726f, 114782.269824628252536f, + 114806.812338514835574f, 114831.356164098819136f, 114855.901301239980967f, + 114880.447749798215227f, 114904.995509633372421f, 114929.544580605404917f, + 114954.094962574250530f, 114978.646655399919837f, 115003.199658942467067f, + 115027.753973061946454f, 115052.309597618470434f, 115076.866532472180552f, + 115101.424777483291109f, 115125.984332512001856f, 115150.545197418585303f, + 115175.107372063343064f, 115199.670856306591304f, 115224.235650008733501f, + 115248.801753030144027f, 115273.369165231299121f, 115297.937886472660466f, + 115322.507916614762507f, 115347.079255518168793f, 115371.651903043471975f, + 115396.225859051293810f, 115420.801123402314261f, 115445.377695957242395f, + 115469.955576576816384f, 115494.534765121818054f, 115519.115261453058338f, + 115543.697065431406372f, 115568.280176917760400f, 115592.864595773033216f, + 115617.450321858195821f, 115642.037355034248321f, 115666.625695162234479f, + 115691.215342103227158f, 115715.806295718357433f, 115740.398555868756375f, + 115764.992122415627819f, 115789.586995220175595f, 115814.183174143676297f, + 115838.780659047435620f, 115863.379449792759260f, 115887.979546241054777f, + 115912.580948253700626f, 115937.183655692162574f, 115961.787668417920941f, + 115986.392986292485148f, 116010.999609177422826f, 116035.607536934316158f, + 116060.216769424790982f, 116084.827306510531344f, 116109.439148053221288f, + 116134.052293914603069f, 116158.666743956462597f, 116183.282498040600331f, + 116207.899556028860388f, 116232.517917783159646f, 116257.137583165385877f, + 116281.758552037514164f, 116306.380824261534144f, 116331.004399699493661f, + 116355.629278213426005f, 116380.255459665466333f, 116404.882943917749799f, + 116429.511730832455214f, 116454.141820271775941f, 116478.773212097992655f, + 116503.405906173371477f, 116528.039902360251290f, 116552.675200520970975f, + 116577.311800517942174f, 116601.949702213591081f, 116626.588905470402096f, + 116651.229410150859621f, 116675.871216117506265f, 116700.514323232942843f, + 116725.158731359755620f, 116749.804440360603621f, 116774.451450098174973f, + 116799.099760435201460f, 116823.749371234429418f, 116848.400282358663389f, + 116873.052493670722470f, 116897.706005033483962f, 116922.360816309839720f, + 116947.016927362754359f, 116971.674338055177941f, 116996.333048250133288f, + 117020.993057810672326f, 117045.654366599876084f, 117070.316974480854697f, + 117094.980881316776504f, 117119.646086970838951f, 117144.312591306239483f, + 117168.980394186291960f, 117193.649495474252035f, 117218.319895033477223f, + 117242.991592727325042f, 117267.664588419225765f, 117292.338881972624222f, + 117317.014473250965239f, 117341.691362117795506f, 117366.369548436661717f, + 117391.049032071154215f, 117415.729812884877902f, 117440.411890741524985f, + 117465.095265504744020f, 117489.779937038314529f, 117514.465905205972376f, + 117539.153169871526188f, 117563.841730898828246f, 117588.531588151730830f, + 117613.222741494158981f, 117637.915190790066845f, 117662.608935903408565f, + 117687.303976698211045f, 117712.000313038530294f, 117736.697944788465975f, + 117761.396871812117752f, 117786.097093973672600f, 117810.798611137302942f, + 117835.501423167253961f, 117860.205529927770840f, 117884.910931283186073f, + 117909.617627097803052f, 117934.325617236027028f, 117959.034901562248706f, + 117983.745479940916994f, 118008.457352236509905f, 118033.170518313534558f, + 118057.884978036556276f, 118082.600731270140386f, 118107.317777878924971f, + 118132.036117727577221f, 118156.755750680764322f, 118181.476676603211672f, + 118206.198895359717426f, 118230.922406815036084f, 118255.647210834038560f, + 118280.373307281566667f, 118305.100696022534976f, 118329.829376921872608f, + 118354.559349844581448f, 118379.290614655648824f, 118404.023171220120275f, + 118428.757019403084996f, 118453.492159069646732f, 118478.228590084981988f, + 118502.966312314238166f, 118527.705325622679084f, 118552.445629875524901f, + 118577.187224938083091f, 118601.930110675675678f, 118626.674286953682895f, + 118651.419753637470421f, 118676.166510592505801f, 118700.914557684212923f, + 118725.663894778132089f, 118750.414521739789052f, 118775.166438434753218f, + 118799.919644728623098f, 118824.674140487055411f, 118849.429925575735979f, + 118874.186999860350625f, 118898.945363206657930f, 118923.705015480431030f, + 118948.465956547515816f, 118973.228186273743631f, 118997.991704524989473f, + 119022.756511167201097f, 119047.522606066326261f, 119072.289989088341827f, + 119097.058660099297413f, 119121.828618965228088f, 119146.599865552256233f, + 119171.372399726504227f, 119196.146221354123554f, 119220.921330301338458f, + 119245.697726434358628f, 119270.475409619466518f, 119295.254379722973681f, + 119320.034636611206224f, 119344.816180150548462f, 119369.599010207399260f, + 119394.383126648215693f, 119419.168529339469387f, 119443.955218147661071f, + 119468.743192939349683f, 119493.532453581123264f, 119518.322999939584406f, + 119543.114831881393911f, 119567.907949273241684f, 119592.702351981832180f, + 119617.498039873928064f, 119642.295012816321105f, 119667.093270675832173f, + 119691.892813319311244f, 119716.693640613666503f, 119741.495752425835235f, + 119766.299148622740177f, 119791.103829071405926f, 119815.909793638871633f, + 119840.717042192176450f, 119865.525574598432286f, 119890.335390724765602f, + 119915.146490438361070f, 119939.958873606417910f, 119964.772540096149896f, + 119989.587489774858113f, 120014.403722509829095f, 120039.221238168407581f, + 120064.040036617967417f, 120088.860117725911550f, 120113.681481359701138f, + 120138.504127386782784f, 120163.328055674704956f, 120188.153266090987017f, + 120212.979758503206540f, 120237.807532778999303f, 120262.636588786001084f, + 120287.466926391876768f, 120312.298545464363997f, 120337.131445871214964f, + 120361.965627480196417f, 120386.801090159133309f, 120411.637833775894251f, + 120436.475858198347851f, 120461.315163294420927f, 120486.155748932069400f, + 120510.997614979278296f, 120535.840761304061743f, 120560.685187774506630f, + 120585.530894258670742f, 120610.377880624699173f, 120635.226146740737022f, + 120660.075692474987591f, 120684.926517695683287f, 120709.778622271056520f, + 120734.632006069441559f, 120759.486668959129020f, 120784.342610808496829f, + 120809.199831485952018f, 120834.058330859916168f, 120858.918108798839967f, + 120883.779165171246859f, 120908.641499845645740f, 120933.505112690603710f, + 120958.370003574731527f, 120983.236172366654500f, 121008.103618935041595f, + 121032.972343148605432f, 121057.842344876058633f, 121082.713623986172024f, + 121107.586180347745540f, 121132.460013829637319f, 121157.335124300690950f, + 121182.211511629822780f, 121207.089175685949158f, 121231.968116338073742f, + 121256.848333455171087f, 121281.729826906288508f, 121306.612596560487873f, + 121331.496642286889255f, 121356.381963954612729f, 121381.268561432851129f, + 121406.156434590782737f, 121431.045583297673147f, 121455.936007422758848f, + 121480.827706835392746f, 121505.720681404869538f, 121530.614931000571232f, + 121555.510455491923494f, 121580.407254748351988f, 121605.305328639326035f, + 121630.204677034358610f, 121655.105299802991794f, 121680.007196814782219f, + 121704.910367939344724f, 121729.814813046323252f, 121754.720532005390851f, + 121779.627524686235120f, 121804.535790958616417f, 121829.445330692309653f, + 121854.356143757104292f, 121879.268230022848002f, 121904.181589359403006f, + 121929.096221636689734f, 121954.012126724643167f, 121978.929304493227392f, + 122003.847754812464700f, 122028.767477552377386f, 122053.688472583031398f, + 122078.610739774550893f, 122103.534278997074580f, 122128.459090120755718f, + 122153.385173015805776f, 122178.312527552465326f, 122203.241153600989492f, + 122228.171051031720708f, 122253.102219714943203f, 122278.034659521072172f, + 122302.968370320493705f, 122327.903351983622997f, 122352.839604380962555f, + 122377.777127383000334f, 122402.715920860253391f, 122427.655984683326096f, + 122452.597318722779164f, 122477.539922849275172f, 122502.483796933476697f, + 122527.428940846060868f, 122552.375354457792128f, 122577.323037639420363f, + 122602.271990261724568f, 122627.222212195571046f, 122652.173703311811551f, + 122677.126463481326937f, 122702.080492575056269f, 122727.035790463967714f, + 122751.992357019058545f, 122776.950192111355136f, 122801.909295611898415f, + 122826.869667391802068f, 122851.831307322194334f, 122876.794215274218004f, + 122901.758391119088628f, 122926.723834727992653f, 122951.690545972232940f, + 122976.658524723068695f, 123001.627770851817331f, 123026.598284229869023f, + 123051.570064728570287f, 123076.543112219369505f, 123101.517426573700504f, + 123126.493007663069875f, 123151.469855358984205f, 123176.447969532993739f, + 123201.427350056677824f, 123226.407996801659465f, 123251.389909639590769f, + 123276.373088442138396f, 123301.357533081027213f, 123326.343243427996640f, + 123351.330219354829751f, 123376.318460733338725f, 123401.307967435350292f, + 123426.298739332763944f, 123451.290776297479169f, 123476.284078201439115f, + 123501.278644916601479f, 123526.274476314982167f, 123551.271572268626187f, + 123576.269932649593102f, 123601.269557329986128f, 123626.270446181952138f, + 123651.272599077638006f, 123676.276015889263363f, 123701.280696489033289f, + 123726.286640749240178f, 123751.293848542176420f, 123776.302319740163512f, + 123801.312054215552052f, 123826.323051840750850f, 123851.335312488168711f, + 123876.348836030287202f, 123901.363622339573340f, 123926.379671288552345f, + 123951.396982749793096f, 123976.415556595879025f, 124001.435392699408112f, + 124026.456490933051100f, 124051.478851169478730f, 124076.502473281419952f, + 124101.527357141603716f, 124126.553502622817177f, 124151.580909597876598f, + 124176.609577939612791f, 124201.639507520914776f, 124226.670698214671575f, + 124251.703149893844966f, 124276.736862431382178f, 124301.771835700303200f, + 124326.808069573642570f, 124351.845563924463931f, 124376.884318625845481f, + 124401.924333550952724f, 124426.965608572922065f, 124452.008143564977217f, + 124477.051938400312793f, 124502.096992952196160f, 124527.143307093923795f, + 124552.190880698821275f, 124577.239713640228729f, 124602.289805791544495f, + 124627.341157026181463f, 124652.393767217596178f, 124677.447636239259737f, + 124702.502763964686892f, 124727.559150267421501f, 124752.616795021036523f, + 124777.675698099163128f, 124802.735859375417931f, 124827.797278723475756f, + 124852.859956017040531f, 124877.923891129859840f, 124902.989083935681265f, + 124928.055534308310598f, 124953.123242121597286f, 124978.192207249376224f, + 125003.262429565540515f, 125028.333908944041468f, 125053.406645258815843f, + 125078.480638383844052f, 125103.555888193179271f, 125128.632394560831017f, + 125153.710157360910671f, 125178.789176467515063f, 125203.869451754813781f, + 125228.950983096961863f, 125254.033770368172554f, 125279.117813442702754f, + 125304.203112194794812f, 125329.289666498778388f, 125354.377476228983141f, + 125379.466541259767837f, 125404.556861465520342f, 125429.648436720701284f, + 125454.741266899742186f, 125479.835351877147332f, 125504.930691527435556f, + 125530.027285725169349f, 125555.125134344925755f, 125580.224237261325470f, + 125605.324594349018298f, 125630.426205482697696f, 125655.529070537042571f, + 125680.633189386819140f, 125705.738561906793620f, 125730.845187971775886f, + 125755.953067456604913f, 125781.062200236134231f, 125806.172586185275577f, + 125831.284225178955239f, 125856.397117092128610f, 125881.511261799809290f, + 125906.626659176981775f, 125931.743309098746977f, 125956.861211440162151f, + 125981.980366076342762f, 126007.100772882447927f, 126032.222431733651320f, + 126057.345342505170265f, 126082.469505072251195f, 126107.594919310140540f, + 126132.721585094172042f, 126157.849502299664891f, 126182.978670801981934f, + 126208.109090476529673f, 126233.240761198714608f, 126258.373682844030554f, + 126283.507855287942220f, 126308.643278405987076f, 126333.779952073702589f, + 126358.917876166669885f, 126384.057050560499192f, 126409.197475130858948f, + 126434.339149753403035f, 126459.482074303858099f, 126484.626248657936230f, + 126509.771672691422282f, 126534.918346280101105f, 126560.066269299815758f, + 126585.215441626423853f, 126610.365863135812106f, 126635.517533703925437f, + 126660.670453206679667f, 126685.824621520077926f, 126710.980038520137896f, + 126736.136704082906363f, 126761.294618084444664f, 126786.453780400872347f, + 126811.614190908338060f, 126836.775849482975900f, 126861.938756001021829f, + 126887.102910338682705f, 126912.268312372238142f, 126937.434961977953208f, + 126962.602859032165725f, 126987.772003411228070f, 127012.942394991521724f, + 127038.114033649471821f, 127063.286919261503499f, 127088.461051704085548f, + 127113.636430853759521f, 127138.813056587023311f, 127163.990928780476679f, + 127189.170047310690279f, 127214.350412054292974f, 127239.532022887971834f, + 127264.714879688384826f, 127289.898982332262676f, 127315.084330696350662f, + 127340.270924657437718f, 127365.458764092341880f, 127390.647848877881188f, + 127415.838178890931886f, 127441.029754008413875f, 127466.222574107247056f, + 127491.416639064394985f, 127516.611948756850325f, 127541.808503061649390f, + 127567.006301855828497f, 127592.205345016467618f, 127617.405632420704933f, + 127642.607163945678622f, 127667.809939468555967f, 127693.013958866533358f, + 127718.219222016879939f, 127743.425728796821204f, 127768.633479083684506f, + 127793.842472754782648f, 127819.052709687486640f, 127844.264189759167493f, + 127869.476912847239873f, 127894.690878829176654f, 127919.906087582421605f, + 127945.122538984520361f, 127970.340232912974898f, 127995.559169245374505f, + 128020.779347859323025f, 128046.000768632438849f, 128071.223431442369474f, + 128096.447336166835157f, 128121.672482683527051f, 128146.898870870209066f, + 128172.126500604645116f, 128197.355371764671872f, 128222.585484228096902f, + 128247.816837872815086f, 128273.049432576706749f, 128298.283268217710429f, + 128323.518344673793763f, 128348.754661822938942f, 128373.992219543157262f, + 128399.231017712518224f, 128424.471056209091330f, 128449.712334910975187f, + 128474.954853696312057f, 128500.198612443287857f, 128525.443611030088505f, + 128550.689849334943574f, 128575.937327236126293f, 128601.186044611909892f, + 128626.436001340611256f, 128651.687197300590924f, 128676.939632370209438f, + 128702.193306427900097f, 128727.448219352081651f, 128752.704371021245606f, + 128777.961761313854367f, 128803.220390108457650f, 128828.480257283619721f, + 128853.741362717919401f, 128879.003706289964612f, 128904.267287878406933f, + 128929.532107361927046f, 128954.798164619234740f, 128980.065459529054351f, + 129005.333991970153875f, 129030.603761821344960f, 129055.874768961424707f, + 129081.147013269262970f, 129106.420494623758714f, 129131.695212903796346f, + 129156.971167988347588f, 129182.248359756355057f, 129207.526788086848683f, + 129232.806452858843841f, 129258.087353951414116f, 129283.369491243647644f, + 129308.652864614661667f, 129333.937473943602527f, 129359.223319109660224f, + 129384.510399992024759f, 129409.798716469973442f, 129435.088268422739930f, + 129460.379055729630636f, 129485.671078269981081f, 129510.964335923141334f, + 129536.258828568505123f, 129561.554556085480726f, 129586.851518353520078f, + 129612.149715252089663f, 129637.449146660699625f, 129662.749812458874658f, + 129688.051712526197662f, 129713.354846742236987f, 129738.659214986633742f, + 129763.964817139029037f, 129789.271653079093085f, 129814.579722686554305f, + 129839.889025841155672f, 129865.199562422640156f, 129890.511332310823491f, + 129915.824335385535960f, 129941.138571526622400f, 129966.454040613971301f, + 129991.770742527500261f, 130017.088677147155977f, 130042.407844352899701f, + 130067.728244024736341f, 130093.049876042714459f, 130118.372740286868066f, + 130143.696836637318484f, 130169.022164974157931f, 130194.348725177551387f, + 130219.676517127663828f, 130245.005540704703890f, 130270.335795788909309f, + 130295.667282260546926f, 130320.999999999912689f, 130346.333948887331644f, + 130371.669128803143394f, 130397.005539627731196f, 130422.343181241521961f, + 130447.682053524942603f, 130473.022156358449138f, 130498.363489622555790f, + 130523.706053197791334f, 130549.049846964699100f, 130574.394870803880622f, + 130599.741124595922884f, 130625.088608221485629f, 130650.437321561228600f, + 130675.787264495869749f, 130701.138436906127026f, 130726.490838672747486f, + 130751.844469676536391f, 130777.199329798313556f, 130802.555418918898795f, + 130827.912736919184681f, 130853.271283680063789f, 130878.631059082472348f, + 130903.992063007375691f, 130929.354295335753704f, 130954.717755948615377f, + 130980.082444727027905f, 131005.448361552058486f, 131030.815506304817973f, + 131056.183878866417217f, 131081.553479118039832f, 131106.924306940869428f, + 131132.296362216118723f, 131157.669644825044088f, 131183.044154648901895f, + 131208.419891569035826f, 131233.796855466760462f, 131259.175046223419486f, + 131284.554463720414788f, 131309.935107839177363f, 131335.316978461167309f, + 131360.700075467844727f, 131386.084398740698816f, 131411.469948161276989f, + 131436.856723611155758f, 131462.244724971940741f, 131487.633952125208452f, + 131513.024404952622717f, 131538.416083335876465f, 131563.808987156633520f, + 131589.203116296703229f, 131614.598470637778519f, 131639.995050061697839f, + 131665.392854450241430f, 131690.791883685305947f, 131716.192137648729840f, + 131741.593616222409764f, 131766.996319288300583f, 131792.400246728386264f, + 131817.805398424621671f, 131843.211774259048980f, 131868.619374113710364f, + 131894.028197870648000f, 131919.438245412020478f, 131944.849516619928181f, + 131970.262011376558803f, 131995.675729564070934f, 132021.090671064681374f, + 132046.506835760665126f, 132071.924223534297198f, 132097.342834267823491f, + 132122.762667843664531f, 132148.183724144095322f, 132173.606003051565494f, + 132199.029504448466469f, 132224.454228217218770f, 132249.880174240359338f, + 132275.307342400308698f, 132300.735732579661999f, 132326.165344660956180f, + 132351.596178526757285f, 132377.028234059689566f, 132402.461511142435484f, + 132427.896009657590184f, 132453.331729487894336f, 132478.768670516088605f, + 132504.206832624913659f, 132529.646215697139269f, 132555.086819615593413f, + 132580.528644263104070f, 132605.971689522528322f, 132631.415955276781460f, + 132656.861441408807877f, 132682.308147801493760f, 132707.756074337870814f, + 132733.205220900941640f, 132758.655587373737944f, 132784.107173639291432f, + 132809.559979580750223f, 132835.014005081175128f, 132860.469250023772474f, + 132885.925714291661279f, 132911.383397768106079f, 132936.842300336284097f, + 132962.302421879459871f, 132987.763762280956144f, 133013.226321424066555f, + 133038.690099192142952f, 133064.155095468537183f, 133089.621310136659304f, + 133115.088743079948472f, 133140.557394181843847f, 133166.027263325813692f, + 133191.498350395413581f, 133216.970655274140881f, 133242.444177845609374f, + 133267.918917993345531f, 133293.394875601021340f, 133318.872050552279688f, + 133344.350442730792565f, 133369.830052020231960f, 133395.310878304386279f, + 133420.792921467014821f, 133446.276181391847786f, 133471.760657962760888f, + 133497.246351063571637f, 133522.733260578155750f, 133548.221386390388943f, + 133573.710728384263348f, 133599.201286443654681f, 133624.693060452613281f, + 133650.186050295102177f, 133675.680255855171708f, 133701.175677016901318f, + 133726.672313664370449f, 133752.170165681716753f, 133777.669232953048777f, + 133803.169515362591483f, 133828.671012794540729f, 133854.173725133092375f, + 133879.677652262529591f, 133905.182794067135546f, 133930.689150431251619f, + 133956.196721239160979f, 133981.705506375263212f, 134007.215505723987008f, + 134032.726719169702847f, 134058.239146596897626f, 134083.752787890000036f, + 134109.267642933584284f, 134134.783711612166371f, 134160.300993810262298f, + 134185.819489412504481f, 134211.339198303525336f, 134236.860120367899071f, + 134262.382255490374519f, 134287.905603555584094f, 134313.430164448305732f, + 134338.955938053259160f, 134364.482924255251419f, 134390.011122939089546f, + 134415.540533989551477f, 134441.071157291589770f, 134466.602992730011465f, + 134492.136040189798223f, 134517.670299555844394f, 134543.205770713160746f, + 134568.742453546758043f, 134594.280347941588843f, 134619.819453782780329f, + 134645.359770955372369f, 134670.901299344521249f, 134696.444038835295942f, + 134721.987989312910940f, 134747.533150662522530f, 134773.079522769374307f, + 134798.627105518709868f, 134824.175898795772810f, 134849.725902485894039f, + 134875.277116474375362f, 134900.829540646605892f, 134926.383174887916539f, + 134951.938019083725521f, 134977.494073119509267f, 135003.051336880685994f, + 135028.609810252761235f, 135054.169493121269625f, 135079.730385371716693f, + 135105.292486889666179f, 135130.855797560769133f, 135156.420317270618398f, + 135181.986045904835919f, 135207.552983349160058f, 135233.121129489241866f, + 135258.690484210877912f, 135284.261047399748350f, 135309.832818941678852f, + 135335.405798722495092f, 135360.979986628022743f, 135386.555382544116583f, + 135412.131986356689595f, 135437.709797951683868f, 135463.288817214983283f, + 135488.869044032617239f, 135514.450478290556930f, 135540.033119874860859f, + 135565.616968671558425f, 135591.202024566766340f, 135616.788287446543109f, + 135642.375757197063649f, 135667.964433704473777f, 135693.554316854977515f, + 135719.145406534749782f, 135744.737702630111016f, 135770.331205027265241f, + 135795.925913612532895f, 135821.521828272234416f, 135847.118948892719345f, + 135872.717275360395433f, 135898.316807561612222f, 135923.917545382835669f, + 135949.519488710531732f, 135975.122637431137264f, 136000.726991431234637f, + 136026.332550597289810f, 136051.939314815914258f, 136077.547283973690355f, + 136103.156457957229577f, 136128.766836653172504f, 136154.378419948217925f, + 136179.991207729006419f, 136205.605199882324087f, 136231.220396294898819f, + 136256.836796853487613f, 136282.454401444934774f, 136308.073209956026403f, + 136333.693222273665015f, 136359.314438284694916f, 136384.936857876076829f, + 136410.560480934684165f, 136436.185307347535854f, 136461.811337001563516f, + 136487.438569783844287f, 136513.067005581426201f, 136538.696644281299086f, + 136564.327485770656494f, 136589.959529936546460f, 136615.592776666162536f, + 136641.227225846669171f, 136666.862877365230815f, 136692.499731109157437f, + 136718.137786965642590f, 136743.777044821967138f, 136769.417504565470153f, + 136795.059166083461605f, 136820.702029263309669f, 136846.346093992440728f, + 136871.991360158193856f, 136897.637827648053644f, 136923.285496349475579f, + 136948.934366149973357f, 136974.584436937060673f, 137000.235708598251222f, + 137025.888181021146011f, 137051.541854093316942f, 137077.196727702423232f, + 137102.852801736094989f, 137128.510076082020532f, 137154.168550627859076f, + 137179.828225261415355f, 137205.489099870406790f, 137231.151174342579907f, + 137256.814448565797647f, 137282.478922427893849f, 137308.144595816673245f, + 137333.811468620086089f, 137359.479540726024425f, 137385.148812022409402f, + 137410.819282397191273f, 137436.490951738436706f, 137462.163819934066851f, + 137487.837886872206582f, 137513.513152440893464f, 137539.189616528223269f, + 137564.867279022291768f, 137590.546139811311150f, 137616.226198783377185f, + 137641.907455826760270f, 137667.589910829672590f, 137693.273563680326333f, + 137718.958414267020999f, 137744.644462478085188f, 137770.331708201818401f, + 137796.020151326607447f, 137821.709791740810033f, 137847.400629332842072f, + 137873.092663991148584f, 137898.785895604174584f, 137924.480324060423300f, + 137950.175949248368852f, 137975.872771056601778f, 138001.570789373654407f, + 138027.270004088146379f, 138052.970415088639129f, 138078.672022263839608f, + 138104.374825502396561f, 138130.078824692958733f, 138155.784019724320387f, + 138181.490410485159373f, 138207.197996864299057f, 138232.906778750504600f, + 138258.616756032628473f, 138284.327928599494044f, 138310.040296339953784f, + 138335.753859142976580f, 138361.468616897444008f, 138387.184569492324954f, + 138412.901716816588305f, 138438.620058759232052f, 138464.339595209312392f, + 138490.060326055856422f, 138515.782251187978545f, 138541.505370494734962f, + 138567.229683865298284f, 138592.955191188841127f, 138618.681892354506999f, + 138644.409787251526723f, 138670.138875769131118f, 138695.869157796580112f, + 138721.600633223162731f, 138747.333301938226214f, 138773.067163831059588f, + 138798.802218791039195f, 138824.538466707570478f, 138850.275907470058883f, + 138876.014540967938956f, 138901.754367090703454f, 138927.495385727816029f, + 138953.237596768798539f, 138978.981000103201950f, 139004.725595620606327f, + 139030.471383210591739f, 139056.218362762796460f, 139081.966534166829661f, + 139107.715897312387824f, 139133.466452089167433f, 139159.218198386894073f, + 139184.971136095322436f, 139210.725265104207210f, 139236.480585303361295f, + 139262.237096582568483f, 139287.994798831758089f, 139313.753691940713907f, + 139339.513775799423456f, 139365.275050297757844f, 139391.037515325675486f, + 139416.801170773163904f, 139442.566016530239722f, 139468.332052486890461f, + 139494.099278533220058f, 139519.867694559274241f, 139545.637300455156947f, + 139571.408096111001214f, 139597.180081416969188f, 139622.953256263223011f, + 139648.727620540012140f, 139674.503174137498718f, 139700.279916946019512f, + 139726.057848855794873f, 139751.836969757132465f, 139777.617279540427262f, + 139803.398778095957823f, 139829.181465314148227f, 139854.965341085393447f, + 139880.750405300146667f, 139906.536657848861068f, 139932.324098621989833f, + 139958.112727510073455f, 139983.902544403652428f, 140009.693549193267245f, + 140035.485741769487504f, 140061.279122022941010f, 140087.073689844284672f, + 140112.869445124146296f, 140138.666387753211893f, 140164.464517622196581f, + 140190.263834621844580f, 140216.064338642929215f, 140241.866029576223809f, + 140267.668907312530791f, 140293.472971742681693f, 140319.278222757537151f, + 140345.084660248016007f, 140370.892284104978899f, 140396.701094219431980f, + 140422.511090482264990f, 140448.322272784484085f, 140474.134641017124522f, + 140499.948195071221562f, 140525.762934837810462f, 140551.578860208013793f, + 140577.395971072895918f, 140603.214267323637614f, 140629.033748851361452f, + 140654.854415547306417f, 140680.676267302624183f, 140706.499304008582840f, + 140732.323525556450477f, 140758.148931837495184f, 140783.975522743043257f, + 140809.803298164420994f, 140835.632257992983796f, 140861.462402120145271f, + 140887.293730437289923f, 140913.126242835860467f, 140938.959939207328716f, + 140964.794819443166489f, 140990.630883434874704f, 141016.468131074012490f, + 141042.306562252138974f, 141068.146176860813284f, 141093.986974791681860f, + 141119.828955936362036f, 141145.672120186500251f, 141171.516467433772050f, + 141197.361997569940286f, 141223.208710486680502f, 141249.056606075784657f, + 141274.905684229044709f, 141300.755944838223513f, 141326.607387795200339f, + 141352.460012991796248f, 141378.313820319919614f, 141404.168809671478812f, + 141430.024980938382214f, 141455.882334012596402f, 141481.740868786117062f, + 141507.600585150939878f, 141533.461482999089640f, 141559.323562222649343f, + 141585.186822713643778f, 141611.051264364214148f, 141636.916887066501658f, + 141662.783690712618409f, 141688.651675194792915f, 141714.520840405195486f, + 141740.391186236054637f, 141766.262712579627987f, 141792.135419328202261f, + 141818.009306374064181f, 141843.884373609558679f, 141869.760620927001582f, + 141895.638048218796030f, 141921.516655377345160f, 141947.396442295052111f, + 141973.277408864378231f, 141999.159554977784865f, 142025.042880527762463f, + 142050.927385406888789f, 142076.813069507654291f, 142102.699932722636731f, + 142128.587974944442976f, 142154.477196065708995f, 142180.367595979041653f, + 142206.259174577135127f, 142232.151931752654491f, 142258.045867398381233f, + 142283.940981406980427f, 142309.837273671262665f, 142335.734744084009435f, + 142361.633392538060434f, 142387.533218926197151f, 142413.434223141317489f, + 142439.336405076348456f, 142465.239764624129748f, 142491.144301677646581f, + 142517.050016129825963f, 142542.956907873682212f, 142568.864976802229648f, + 142594.774222808482591f, 142620.684645785513567f, 142646.596245626365999f, + 142672.509022224228829f, 142698.422975472145481f, 142724.338105263334000f, + 142750.254411490925122f, 142776.171894048165996f, 142802.090552828274667f, + 142828.010387724469183f, 142853.931398630084004f, 142879.853585438366281f, + 142905.776948042679578f, 142931.701486336358357f, 142957.627200212766184f, + 142983.554089565324830f, 143009.482154287426965f, 143035.411394272552570f, + 143061.341809414152522f, 143087.273399605706800f, 143113.206164740753593f, + 143139.140104712831089f, 143165.075219415506581f, 143191.011508742376463f, + 143216.948972587037133f, 143242.887610843143193f, 143268.827423404349247f, + 143294.768410164368106f, 143320.710571016883478f, 143346.653905855637277f, + 143372.598414574371418f, 143398.544097066915128f, 143424.490953227010323f, + 143450.438982948573539f, 143476.388186125375796f, 143502.338562651333632f, + 143528.290112420363585f, 143554.242835326382192f, 143580.196731263335096f, + 143606.151800125197042f, 143632.108041805971880f, 143658.065456199692562f, + 143684.024043200392043f, 143709.983802702132380f, 143735.944734599004732f, + 143761.906838785187574f, 143787.870115154742962f, 143813.834563601878472f, + 143839.800184020801680f, 143865.766976305691060f, 143891.734940350812394f, + 143917.704076050402364f, 143943.674383298755856f, 143969.645861990196863f, + 143995.618512019049376f, 144021.592333279666491f, 144047.567325666459510f, + 144073.543489073781529f, 144099.520823396072956f, 144125.499328527832404f, + 144151.479004363500280f, 144177.459850797575200f, 144203.441867724584881f, + 144229.425055039086146f, 144255.409412635635817f, 144281.394940408848925f, + 144307.381638253311394f, 144333.369506063725566f, 144359.358543734677369f, + 144385.348751160927350f, 144411.340128237177851f, 144437.332674858131213f, + 144463.326390918547986f, 144489.321276313246926f, 144515.317330937046790f, + 144541.314554684737232f, 144567.312947451195214f, 144593.312509131297702f, + 144619.313239619950764f, 144645.315138812060468f, 144671.318206602620194f, + 144697.322442886565113f, 144723.327847558888607f, 144749.334420514671365f, + 144775.342161648877664f, 144801.351070856646402f, 144827.361148033029167f, + 144853.372393073135754f, 144879.384805872134166f, 144905.398386325163301f, + 144931.413134327420266f, 144957.429049774102168f, 144983.446132560464321f, + 145009.464382581732934f, 145035.483799733221531f, 145061.504383910214528f, + 145087.526135008054553f, 145113.549052922055125f, 145139.573137547646184f, + 145165.598388780170353f, 145191.624806515086675f, 145217.652390647825086f, + 145243.681141073844628f, 145269.711057688633446f, 145295.742140387737891f, + 145321.774389066675212f, 145347.807803620991763f, 145373.842383946292102f, + 145399.878129938180791f, 145425.915041492291493f, 145451.953118504257873f, + 145477.992360869800905f, 145504.032768484583357f, 145530.074341244355310f, + 145556.117079044837737f, 145582.160981781809824f, 145608.206049351079855f, + 145634.252281648485223f, 145660.299678569805110f, 145686.348240010964219f, + 145712.397965867829043f, 145738.448856036295183f, 145764.500910412316443f, + 145790.554128891846631f, 145816.608511370868655f, 145842.664057745365426f, + 145868.720767911407165f, 145894.778641765005887f, 145920.837679202260915f, + 145946.897880119242473f, 145972.959244412078988f, 145999.021771976927994f, + 146025.085462709947024f, 146051.150316507322714f, 146077.216333265270805f, + 146103.283512880036142f, 146129.351855247892672f, 146155.421360265056137f, + 146181.492027827916900f, 146207.563857832719805f, 146233.636850175884319f, + 146259.711004753771704f, 146285.786321462743217f, 146311.862800199276535f, + 146337.940440859762020f, 146364.019243340706453f, 146390.099207538558403f, + 146416.180333349853754f, 146442.262620671157492f, 146468.346069398976397f, + 146494.430679429933662f, 146520.516450660623377f, 146546.603382987639634f, + 146572.691476307692938f, 146598.780730517406482f, 146624.871145513519878f, + 146650.962721192743629f, 146677.055457451788243f, 146703.149354187451536f, + 146729.244411296502221f, 146755.340628675767221f, 146781.438006222073454f, + 146807.536543832276948f, 146833.636241403291933f, 146859.737098831974436f, + 146885.839116015267791f, 146911.942292850144440f, 146938.046629233547719f, + 146964.152125062479172f, 146990.258780233969446f, 147016.366594645049190f, + 147042.475568192807259f, 147068.585700774274301f, 147094.696992286597379f, + 147120.809442626923556f, 147146.923051692370791f, 147173.037819380144356f, + 147199.153745587449521f, 147225.270830211491557f, 147251.389073149533942f, + 147277.508474298811052f, 147303.629033556644572f, 147329.750750820356188f, + 147355.873625987267587f, 147381.997658954729559f, 147408.122849620151101f, + 147434.249197880912106f, 147460.376703634479782f, 147486.505366778263124f, + 147512.635187209758442f, 147538.766164826462045f, 147564.898299525870243f, + 147591.031591205566656f, 147617.166039763076697f, 147643.301645096013090f, + 147669.438407101988560f, 147695.576325678586727f, 147721.715400723536732f, + 147747.855632134451298f, 147773.997019809088670f, 147800.139563645119779f, + 147826.283263540331973f, 147852.428119392483495f, 147878.574131099332590f, + 147904.721298558724811f, 147930.869621668505715f, 147957.019100326520856f, + 147983.169734430615790f, 148009.321523878752487f, 148035.474468568834709f, + 148061.628568398824427f, 148087.783823266654508f, 148113.940233070345130f, + 148140.097797707916470f, 148166.256517077388708f, 148192.416391076869331f, + 148218.577419604378520f, 148244.739602558081970f, 148270.902939836058067f, + 148297.067431336501613f, 148323.233076957549201f, 148349.399876597424736f, + 148375.567830154323019f, 148401.736937526526162f, 148427.907198612258071f, + 148454.078613309829962f, 148480.251181517523946f, 148506.424903133680345f, + 148532.599778056668583f, 148558.775806184858084f, 148584.952987416647375f, + 148611.131321650434984f, 148637.310808784706751f, 148663.491448717890307f, + 148689.673241348500596f, 148715.856186575023457f, 148742.040284296002937f, + 148768.225534409983084f, 148794.411936815566150f, 148820.599491411325289f, + 148846.788198095891858f, 148872.978056767926319f, 148899.169067326060031f, + 148925.361229669011664f, 148951.554543695470784f, 148977.749009304185165f, + 149003.944626393902581f, 149030.141394863399910f, 149056.339314611512236f, + 149082.538385536987334f, 149108.738607538747601f, 149134.939980515599018f, + 149161.142504366463982f, 149187.346178990264889f, 149213.551004285895033f, + 149239.756980152335018f, 149265.964106488536345f, 149292.172383193537826f, + 149318.381810166349169f, 149344.592387305980083f, 149370.804114511556691f, + 149397.016991682117805f, 149423.231018716789549f, 149449.446195514727151f, + 149475.662521975027630f, 149501.879997996933525f, 149528.098623479600064f, + 149554.318398322269786f, 149580.539322424185229f, 149606.761395684588933f, + 149632.984618002781644f, 149659.208989278093213f, 149685.434509409824386f, + 149711.661178297334118f, 149737.888995840010466f, 149764.117961937241489f, + 149790.348076488444349f, 149816.579339393094415f, 149842.811750550608849f, + 149869.045309860463021f, 149895.280017222219612f, 149921.515872535383096f, + 149947.752875699516153f, 149973.991026614152361f, 150000.230325178912608f, + 150026.470771293417783f, 150052.712364857317880f, 150078.955105770262890f, + 150105.198993931902805f, 150131.444029242004035f, 150157.690211600245675f, + 150183.937540906394133f, 150210.186017060244922f, 150236.435639961535344f, + 150262.686409510119120f, 150288.938325605820864f, 150315.191388148523401f, + 150341.445597038051346f, 150367.700952174374834f, 150393.957453457347583f, + 150420.215100786968833f, 150446.473894063208718f, 150472.733833186008269f, + 150498.994918055424932f, 150525.257148571457947f, 150551.520524634193862f, + 150577.785046143690124f, 150604.050713000033284f, 150630.317525103368098f, + 150656.585482353839325f, 150682.854584651591722f, 150709.124831896799151f, + 150735.396223989722785f, 150761.668760830507381f, 150787.942442319501424f, + 150814.217268356907880f, 150840.493238843017025f, 150866.770353678206448f, + 150893.048612762766425f, 150919.328015997045441f, 150945.608563281479292f, + 150971.890254516416462f, 150998.173089602292748f, 151024.457068439573050f, + 151050.742190928722266f, 151077.028456970205298f, 151103.315866464545252f, + 151129.604419312294340f, 151155.894115414004773f, 151182.184954670199659f, + 151208.476936981547624f, 151234.770062248629984f, 151261.064330372086260f, + 151287.359741252585081f, 151313.656294790824177f, 151339.953990887472173f, + 151366.252829443285009f, 151392.552810359018622f, 151418.853933535428951f, + 151445.156198873301037f, 151471.459606273449026f, 151497.764155636745272f, + 151524.069846863974817f, 151550.376679856068222f, 151576.684654513926944f, + 151602.993770738452440f, 151629.304028430575272f, 151655.615427491284208f, + 151681.927967821568018f, 151708.241649322415469f, 151734.556471894844435f, + 151760.872435439930996f, 151787.189539858722128f, 151813.507785052352119f, + 151839.827170921867946f, 151866.147697368462104f, 151892.469364293268882f, + 151918.792171597480774f, 151945.116119182290277f, 151971.441206948889885f, + 151997.767434798559407f, 152024.094802632549545f, 152050.423310352140106f, + 152076.752957858640002f, 152103.083745053387247f, 152129.415671837719856f, + 152155.748738113034051f, 152182.082943780667847f, 152208.418288742075674f, + 152234.754772898711963f, 152261.092396151972935f, 152287.431158403371228f, + 152313.771059554390376f, 152340.112099506572122f, 152366.454278161458205f, + 152392.797595420561265f, 152419.142051185539458f, 152445.487645357934525f, + 152471.834377839404624f, 152498.182248531607911f, 152524.531257336173439f, + 152550.881404154817574f, 152577.232688889256679f, 152603.585111441207118f, + 152629.938671712414362f, 152656.293369604682084f, 152682.649205019784858f, + 152709.006177859555464f, 152735.364288025826681f, 152761.723535420431290f, + 152788.083919945289381f, 152814.445441502291942f, 152840.808099993329961f, + 152867.171895320381736f, 152893.536827385425568f, 152919.902896090410650f, + 152946.270101337373490f, 152972.638443028321490f, 152999.007921065291157f, + 153025.378535350406310f, 153051.750285785703454f, 153078.123172273335513f, + 153104.497194715397200f, 153130.872353014099644f, 153157.248647071566666f, + 153183.626076790009392f, 153210.004642071668059f, 153236.384342818753794f, + 153262.765178933535935f, 153289.147150318283821f, 153315.530256875354098f, + 153341.914498507016106f, 153368.299875115597388f, 153394.686386603541905f, + 153421.074032873148099f, 153447.462813826889032f, 153473.852729367179563f, + 153500.243779396434547f, 153526.635963817156153f, 153553.029282531817444f, + 153579.423735442949692f, 153605.819322453084169f, 153632.216043464781251f, + 153658.613898380572209f, 153685.012887103104731f, 153711.413009534968296f, + 153737.814265578810591f, 153764.216655137279304f, 153790.620178113051224f, + 153817.024834408861352f, 153843.430623927386478f, 153869.837546571390703f, + 153896.245602243667236f, 153922.654790846921969f, 153949.065112284035422f, + 153975.476566457800800f, 154001.889153271069517f, 154028.302872626692988f, + 154054.717724427609937f, 154081.133708576671779f, 154107.550824976817239f, + 154133.969073531014146f, 154160.388454142230330f, 154186.808966713462723f, + 154213.230611147737363f, 154239.653387348051183f, 154266.077295217459323f, + 154292.502334659075132f, 154318.928505575982854f, 154345.355807871266734f, + 154371.784241448098328f, 154398.213806209649192f, 154424.644502059032675f, + 154451.076328899507644f, 154477.509286634274758f, 154503.943375166592887f, + 154530.378594399691792f, 154556.814944236888550f, 154583.252424581442028f, + 154609.691035336727509f, 154636.130776406032965f, 154662.571647692791885f, + 154689.013649100321345f, 154715.456780532083940f, 154741.901041891454952f, + 154768.346433081926079f, 154794.792954006959917f, 154821.240604570019059f, + 154847.689384674624307f, 154874.139294224325567f, 154900.590333122643642f, + 154927.042501273157541f, 154953.495798579475377f, 154979.950224945205264f, + 155006.405780273955315f, 155032.862464469420956f, 155059.320277435239404f, + 155085.779219075135188f, 155112.239289292803733f, 155138.700487991969567f, + 155165.162815076415427f, 155191.626270449894946f, 155218.090854016249068f, + 155244.556565679231426f, 155271.023405342741171f, 155297.491372910590144f, + 155323.960468286677497f, 155350.430691374902381f, 155376.902042079193052f, + 155403.374520303477766f, 155429.848125951713882f, 155456.322858927887864f, + 155482.798719136015279f, 155509.275706480111694f, 155535.753820864221780f, + 155562.233062192390207f, 155588.713430368719855f, 155615.194925297313603f, + 155641.677546882274328f, 155668.161295027792221f, 155694.646169637970161f, + 155721.132170617056545f, 155747.619297869212460f, 155774.107551298686303f, + 155800.596930809726473f, 155827.087436306610471f, 155853.579067693586694f, + 155880.071824874961749f, 155906.565707755129552f, 155933.060716238367604f, + 155959.556850229098927f, 155986.054109631659230f, 156012.552494350500638f, + 156039.052004290017067f, 156065.552639354718849f, 156092.054399448999902f, + 156118.557284477399662f, 156145.061294344428461f, 156171.566428954596631f, + 156198.072688212472713f, 156224.580072022596141f, 156251.088580289593665f, + 156277.598212918092031f, 156304.108969812659780f, 156330.620850878010970f, + 156357.133856018801453f, 156383.647985139687080f, 156410.163238145440118f, + 156436.679614940745523f, 156463.197115430404665f, 156489.715739519131603f, + 156516.235487111756811f, 156542.756358113110764f, 156569.278352427994832f, + 156595.801469961268594f, 156622.325710617820732f, 156648.851074302539928f, + 156675.377560920314863f, 156701.905170376121532f, 156728.433902574906824f, + 156754.963757421617629f, 156781.494734821288148f, 156808.026834678894375f, + 156834.560056899528718f, 156861.094401388167171f, 156887.629868049931247f, + 156914.166456789942458f, 156940.704167513264110f, 156967.243000125046819f, + 156993.782954530470306f, 157020.324030634685187f, 157046.866228342900285f, + 157073.409547560324427f, 157099.953988192195538f, 157126.499550143780652f, + 157153.046233320317697f, 157179.594037627161015f, 157206.142962969577638f, + 157232.693009252921911f, 157259.244176382577280f, 157285.796464263868984f, + 157312.349872802209575f, 157338.904401903040707f, 157365.460051471745828f, + 157392.016821413853904f, 157418.574711634777486f, 157445.133722040045541f, + 157471.693852535128826f, 157498.255103025643621f, 157524.817473417060683f, + 157551.380963615025394f, 157577.945573525095824f, 157604.511303052859148f, + 157631.078152104018955f, 157657.646120584162418f, 157684.215208399022231f, + 157710.785415454272879f, 157737.356741655588849f, 157763.929186908761039f, + 157790.502751119522145f, 157817.077434193633962f, 157843.653236036916496f, + 157870.230156555160647f, 157896.808195654215524f, 157923.387353239901131f, + 157949.967629218124785f, 157976.549023494793801f, 158003.131535975757288f, + 158029.715166567009874f, 158056.299915174487978f, 158082.885781704157125f, + 158109.472766061982838f, 158136.060868154017953f, 158162.650087886286201f, + 158189.240425164840417f, 158215.831879895733437f, 158242.424451985047199f, + 158269.018141338921851f, 158295.612947863468435f, 158322.208871464856202f, + 158348.805912049225299f, 158375.404069522803184f, 158402.003343791759107f, + 158428.603734762349632f, 158455.205242340802215f, 158481.807866433373420f, + 158508.411606946407119f, 158535.016463786159875f, 158561.622436858975561f, + 158588.229526071198052f, 158614.837731329200324f, 158641.447052539355354f, + 158668.057489608065225f, 158694.669042441790225f, 158721.281710946932435f, + 158747.895495029981248f, 158774.510394597396953f, 158801.126409555727150f, + 158827.743539811432129f, 158854.361785271117697f, 158880.981145841302350f, + 158907.601621428562794f, 158934.223211939563043f, 158960.845917280850699f, + 158987.469737359089777f, 159014.094672080973396f, 159040.720721353136469f, + 159067.347885082301218f, 159093.976163175189868f, 159120.605555538524641f, + 159147.236062079056865f, 159173.867682703596074f, 159200.500417318893597f, + 159227.134265831817174f, 159253.769228149176342f, 159280.405304177809739f, + 159307.042493824614212f, 159333.680796996486606f, 159360.320213600323768f, + 159386.960743543051649f, 159413.602386731654406f, 159440.245143073087092f, + 159466.889012474333867f, 159493.533994842437096f, 159520.180090084380936f, + 159546.827298107236857f, 159573.475618818047224f, 159600.125052123970818f, + 159626.775597932020901f, 159653.427256149414461f, 159680.080026683252072f, + 159706.733909440692514f, 159733.388904328923672f, 159760.045011255162535f, + 159786.702230126655195f, 159813.360560850589536f, 159840.020003334269859f, + 159866.680557484971359f, 159893.342223209969234f, 159920.005000416625990f, + 159946.668889012245927f, 159973.333888904220657f, 159999.999999999883585f, + 160026.667222206684528f, 160053.335555432015099f, 160080.004999583296012f, + 160106.675554568006191f, 160133.347220293595456f, 160160.019996667600935f, + 160186.693883597501554f, 160213.368880990834441f, 160240.044988755165832f, + 160266.722206798061961f, 160293.400535027089063f, 160320.079973349871580f, + 160346.760521674063057f, 160373.442179907287937f, 160400.124947957199765f, + 160426.808825731510296f, 160453.493813137931284f, 160480.179910084174480f, + 160506.867116477951640f, 160533.555432227090932f, 160560.244857239333214f, + 160586.935391422477551f, 160613.627034684352111f, 160640.319786932814168f, + 160667.013648075691890f, 160693.708618020871654f, 160720.404696676268941f, + 160747.101883949799230f, 160773.800179749378003f, 160800.499583982978947f, + 160827.200096558546647f, 160853.901717384112999f, 160880.604446367651690f, + 160907.308283417223720f, 160934.013228440860985f, 160960.719281346653588f, + 160987.426442042691633f, 161014.134710437036119f, 161040.844086437835358f, + 161067.554569953266764f, 161094.266160891478648f, 161120.978859160619322f, + 161147.692664668924408f, 161174.407577324629528f, 161201.123597035941202f, + 161227.840723711124156f, 161254.558957258472219f, 161281.278297586279223f, + 161307.998744602868101f, 161334.720298216561787f, 161361.442958335712319f, + 161388.166724868700840f, 161414.891597723908490f, 161441.617576809774619f, + 161468.344662034680368f, 161495.072853307123296f, 161521.802150535571855f, + 161548.532553628465394f, 161575.264062494359678f, 161601.996677041752264f, + 161628.730397179198917f, 161655.465222815255402f, 161682.201153858477483f, + 161708.938190217537340f, 161735.676331800990738f, 161762.415578517509857f, + 161789.155930275708670f, 161815.897386984317563f, 161842.639948552008718f, + 161869.383614887483418f, 161896.128385899501154f, 161922.874261496792315f, + 161949.621241588116391f, 161976.369326082291082f, 162003.118514888104983f, + 162029.868807914404897f, 162056.620205070008524f, 162083.372706263820874f, + 162110.126311404688749f, 162136.881020401517162f, 162163.636833163240226f, + 162190.393749598792056f, 162217.151769617106766f, 162243.910893127234885f, + 162270.671120038081426f, 162297.432450258726021f, 162324.194883698190097f, + 162350.958420265495079f, 162377.723059869749704f, 162404.488802420033608f, + 162431.255647825426422f, 162458.023595995065989f, 162484.792646838148357f, + 162511.562800263782265f, 162538.334056181163760f, 162565.106414499488892f, + 162591.879875128011918f, 162618.654437975928886f, 162645.430102952523157f, + 162672.206869967078092f, 162698.984738928877050f, 162725.763709747232497f, + 162752.543782331486000f, 162779.324956590950023f, 162806.107232435053447f, + 162832.890609773166943f, 162859.675088514661184f, 162886.460668569023255f, + 162913.247349845623830f, 162940.035132254008204f, 162966.824015703576151f, + 162993.614000103902072f, 163020.405085364443948f, 163047.197271394805284f, + 163073.990558104473166f, 163100.784945403051097f, 163127.580433200142579f, + 163154.377021405351115f, 163181.174709928309312f, 163207.973498678649776f, + 163234.773387566063320f, 163261.574376500240760f, 163288.376465390872909f, + 163315.179654147650581f, 163341.983942680381006f, 163368.789330898754997f, + 163395.595818712608889f, 163422.403406031720806f, 163449.212092765897978f, + 163476.021878824976739f, 163502.832764118822524f, 163529.644748557300773f, + 163556.457832050276920f, 163583.272014507703716f, 163610.087295839446597f, + 163636.903675955516519f, 163663.721154765837127f, 163690.539732180419378f, + 163717.359408109216020f, 163744.180182462296216f, 163771.002055149641819f, + 163797.825026081380202f, 163824.649095167522319f, 163851.474262318195542f, + 163878.300527443498140f, 163905.127890453557484f, 163931.956351258530049f, + 163958.785909768572310f, 163985.616565893869847f, 164012.448319544637343f, + 164039.281170631089481f, 164066.115119063440943f, 164092.950164751993725f, + 164119.786307606991613f, 164146.623547538736602f, 164173.461884457559790f, + 164200.301318273763172f, 164227.141848897706950f, 164253.983476239780430f, + 164280.826200210314710f, 164307.670020719786407f, 164334.514937678555725f, + 164361.360950997099280f, 164388.208060585864587f, 164415.056266355328262f, + 164441.905568215996027f, 164468.755966078373604f, 164495.607459852995817f, + 164522.460049450397491f, 164549.313734781171661f, 164576.168515755911358f, + 164603.024392285180511f, 164629.881364279659465f, 164656.739431649912149f, + 164683.598594306677114f, 164710.458852160605602f, 164737.320205122377956f, + 164764.182653102703625f, 164791.046196012350265f, 164817.910833762056427f, + 164844.776566262560664f, 164871.643393424688838f, 164898.511315159237711f, + 164925.380331377033144f, 164952.250441988871899f, 164979.121646905696252f, + 165005.993946038302965f, 165032.867339297634317f, 165059.741826594603481f, + 165086.617407840152737f, 165113.494082945195260f, 165140.371851820702432f, + 165167.250714377703844f, 165194.130670527170878f, 165221.011720180133125f, + 165247.893863247620175f, 165274.777099640719825f, 165301.661429270490771f, + 165328.546852048020810f, 165355.433367884455947f, 165382.320976690883981f, + 165409.209678378480021f, 165436.099472858419176f, 165462.990360041876556f, + 165489.882339840056375f, 165516.775412164191948f, 165543.669576925487490f, + 165570.564834035234526f, 165597.461183404695475f, 165624.358624945161864f, + 165651.257158567983424f, 165678.156784184422577f, 165705.057501705887262f, + 165731.959311043698108f, 165758.862212109292159f, 165785.766204814019147f, + 165812.671289069316117f, 165839.577464786620112f, 165866.484731877397280f, + 165893.393090253113769f, 165920.302539825264830f, 165947.213080505374819f, + 165974.124712204938987f, 166001.037434835510794f, 166027.951248308672803f, + 166054.866152536007576f, 166081.782147429068573f, 166108.699232899525668f, + 166135.617408858990530f, 166162.536675219133031f, 166189.457031891593942f, + 166216.378478788101347f, 166243.301015820325119f, 166270.224642899993341f, + 166297.149359938863199f, 166324.075166848691879f, 166351.002063541265670f, + 166377.930049928370863f, 166404.859125921822852f, 166431.789291433466133f, + 166458.720546375116101f, 166485.652890658675460f, 166512.586324195988709f, + 166539.520846899016760f, 166566.456458679633215f, 166593.393159449769882f, + 166620.330949121445883f, 166647.269827606563922f, 166674.209794817172224f, + 166701.150850665231701f, 166728.092995062819682f, 166755.036227921926184f, + 166781.980549154657638f, 166808.925958673091372f, 166835.872456389275612f, + 166862.820042215404101f, 166889.768716063554166f, 166916.718477845919551f, + 166943.669327474606689f, 166970.621264861867530f, 166997.574289919895818f, + 167024.528402560885297f, 167051.483602697087917f, 167078.439890240755631f, + 167105.397265104198596f, 167132.355727199668763f, 167159.315276439505396f, + 167186.275912735989550f, 167213.237636001547799f, 167240.200446148490300f, + 167267.164343089185422f, 167294.129326736088842f, 167321.095397001568926f, + 167348.062553798081353f, 167375.030797038081801f, 167402.000126634025946f, + 167428.970542498398572f, 167455.942044543713564f, 167482.914632682513911f, + 167509.888306827313500f, 167536.863066890684422f, 167563.838912785169668f, + 167590.815844423399540f, 167617.793861718004337f, 167644.772964581556153f, + 167671.753152926714392f, 167698.734426666196669f, 167725.716785712604178f, + 167752.700229978683637f, 167779.684759377152659f, 167806.670373820728855f, + 167833.657073222188046f, 167860.644857494247844f, 167887.633726549771382f, + 167914.623680301476270f, 167941.614718662254745f, 167968.606841544911731f, + 167995.600048862310359f, 168022.594340527313761f, 168049.589716452814173f, + 168076.586176551762037f, 168103.583720737049589f, 168130.582348921598168f, + 168157.582061018416425f, 168184.582856940454803f, 168211.584736600721953f, + 168238.587699912197422f, 168265.591746787977172f, 168292.596877141069854f, + 168319.603090884542326f, 168346.610387931461446f, 168373.618768194981385f, + 168400.628231588169001f, 168427.638778024178464f, 168454.650407416193048f, + 168481.663119677337818f, 168508.676914720796049f, 168535.691792459809221f, + 168562.707752807589713f, 168589.724795677379007f, 168616.742920982418582f, + 168643.762128636008129f, 168670.782418551418232f, 168697.803790641977685f, + 168724.826244820986176f, 168751.849781001830706f, 168778.874399097840069f, + 168805.900099022372160f, 168832.926880688901292f, 168859.954744010756258f, + 168886.983688901411369f, 168914.013715274311835f, 168941.044823042931966f, + 168968.077012120746076f, 168995.110282421228476f, 169022.144633857940789f, + 169049.180066344386432f, 169076.216579794127028f, 169103.254174120724201f, + 169130.292849237797782f, 169157.332605058909394f, 169184.373441497707972f, + 169211.415358467842452f, 169238.458355882932665f, 169265.502433656656649f, + 169292.547591702750651f, 169319.593829934863606f, 169346.641148266760865f, + 169373.689546612149570f, 169400.739024884824175f, 169427.789582998550031f, + 169454.841220867121592f, 169481.893938404333312f, 169508.947735524037853f, + 169536.002612140058773f, 169563.058568166248733f, 169590.115603516547708f, + 169617.173718104779255f, 169644.232911844912451f, 169671.293184650829062f, + 169698.354536436527269f, 169725.416967115947045f, 169752.480476603057468f, + 169779.545064811885823f, 169806.610731656430289f, 169833.677477050747257f, + 169860.745300908864010f, 169887.814203144866042f, 169914.884183672809741f, + 169941.955242406838806f, 169969.027379261038732f, 169996.100594149582321f, + 170023.174886986584170f, 170050.250257686246186f, 170077.326706162741175f, + 170104.404232330241939f, 170131.482836103037698f, 170158.562517395330360f, + 170185.643276121380040f, 170212.725112195446854f, 170239.808025531849125f, + 170266.892016044876073f, 170293.977083648875123f, 170321.063228258135496f, + 170348.150449787062826f, 170375.238748150033643f, 170402.328123261395376f, + 170429.418575035611866f, 170456.510103387088748f, 170483.602708230260760f, + 170510.696389479591744f, 170537.791147049545543f, 170564.886980854673311f, + 170591.983890809409786f, 170619.081876828335226f, 170646.180938825971680f, + 170673.281076716899406f, 170700.382290415698662f, 170727.484579836949706f, + 170754.587944895261899f, 170781.692385505273705f, 170808.797901581652695f, + 170835.904493039037334f, 170863.012159792095190f, 170890.120901755581144f, + 170917.230718844162766f, 170944.341610972565832f, 170971.453578055574326f, + 170998.566620007914025f, 171025.680736744427122f, 171052.795928179839393f, + 171079.912194229022134f, 171107.029534806788433f, 171134.147949827980483f, + 171161.267439207469579f, 171188.388002860156121f, 171215.509640700940508f, + 171242.632352644723142f, 171269.756138606433524f, 171296.880998501030263f, + 171324.006932243471965f, 171351.133939748775447f, 171378.262020931928419f, + 171405.391175707918592f, 171432.521403991820989f, 171459.652705698681530f, + 171486.785080743546132f, 171513.918529041518923f, 171541.053050507704029f, + 171568.188645057205576f, 171595.325312605185900f, 171622.463053066778230f, + 171649.601866357144900f, 171676.741752391477348f, 171703.882711084996117f, + 171731.024742352892645f, 171758.167846110416576f, 171785.312022272846662f, + 171812.457270755403442f, 171839.603591473423876f, 171866.750984342186712f, + 171893.899449276999803f, 171921.048986193229211f, 171948.199595006211894f, + 171975.351275631313911f, 172002.504027983930428f, 172029.657851979456609f, + 172056.812747533345828f, 172083.968714560964145f, 172111.125752977852244f, + 172138.283862699434394f, 172165.443043641193071f, 172192.603295718639856f, + 172219.764618847286329f, 172246.927012942702277f, 172274.090477920399280f, + 172301.255013696005335f, 172328.420620185032021f, 172355.587297303136438f, + 172382.755044965917477f, 172409.923863089032238f, 172437.093751588108717f, + 172464.264710378833115f, 172491.436739376920741f, 172518.609838497999590f, + 172545.784007657843176f, 172572.959246772195911f, 172600.135555756773101f, + 172627.312934527377365f, 172654.491382999782218f, 172681.670901089790277f, + 172708.851488713233266f, 172736.033145785913803f, 172763.215872223721817f, + 172790.399667942518136f, 172817.584532858163584f, 172844.770466886606300f, + 172871.957469943707110f, 172899.145541945443256f, 172926.334682807762874f, + 172953.524892446643207f, 172980.716170778032392f, 173007.908517717936775f, + 173035.101933182420908f, 173062.296417087462032f, 173089.491969349153806f, + 173116.688589883560780f, 173143.886278606718406f, 173171.085035434807651f, + 173198.284860283863964f, 173225.485753070068313f, 173252.687713709543459f, + 173279.890742118499475f, 173307.094838213059120f, 173334.300001909490675f, + 173361.506233123946004f, 173388.713531772693386f, 173415.921897771971999f, + 173443.131331038021017f, 173470.341831487166928f, 173497.553399035707116f, + 173524.766033599909861f, 173551.979735096130753f, 173579.194503440725384f, + 173606.410338550049346f, 173633.627240340487333f, 173660.845208728424041f, + 173688.064243630273268f, 173715.284344962477917f, 173742.505512641480891f, + 173769.727746583725093f, 173796.951046705711633f, 173824.175412923912518f, + 173851.400845154857961f, 173878.627343315049075f, 173905.854907321074279f, + 173933.083537089434685f, 173960.313232536747819f, 173987.543993579602102f, + 174014.775820134615060f, 174042.008712118375115f, 174069.242669447558001f, + 174096.477692038781242f, 174123.713779808778781f, 174150.950932674197247f, + 174178.189150551741477f, 174205.428433358145412f, 174232.668781010172097f, + 174259.910193424526369f, 174287.152670518029481f, 174314.396212207444478f, + 174341.640818409563508f, 174368.886489041236928f, 174396.133224019256886f, + 174423.381023260531947f, 174450.629886681883363f, 174477.879814200248802f, + 174505.130805732478620f, 174532.382861195510486f, 174559.635980506252963f, + 174586.890163581701927f, 174614.145410338824149f, 174641.401720694557298f, + 174668.659094565926353f, 174695.917531869956292f, 174723.177032523642993f, + 174750.437596444069641f, 174777.699223548290320f, 174804.961913753359113f, + 174832.225666976417415f, 174859.490483134548413f, 174886.756362144864397f, + 174914.023303924564971f, 174941.291308390762424f, 174968.560375460627256f, + 174995.830505051388172f, 175023.101697080244776f, 175050.373951464396669f, + 175077.647268121130764f, 175104.921646967646666f, 175132.197087921260390f, + 175159.473590899258852f, 175186.751155818928964f, 175214.029782597586745f, + 175241.309471152606420f, 175268.590221401304007f, 175295.872033261082834f, + 175323.154906649288023f, 175350.438841483352007f, 175377.723837680678116f, + 175405.009895158727886f, 175432.297013834933750f, 175459.585193626728142f, + 175486.874434451659909f, 175514.164736227161484f, 175541.456098870810820f, + 175568.748522300069453f, 175596.042006432544440f, 175623.336551185755525f, + 175650.632156477309763f, 175677.928822224814212f, 175705.226548345817719f, + 175732.525334758014651f, 175759.825181379012065f, 175787.126088126446120f, + 175814.428054918069392f, 175841.731081671488937f, 175869.035168304457329f, + 175896.340314734668937f, 175923.646520879876334f, 175950.953786657861201f, + 175978.262111986347008f, 176005.571496783144539f, 176032.881940966064576f, + 176060.193444452888798f, 176087.506007161515299f, 176114.819629009725759f, + 176142.134309915418271f, 176169.450049796461826f, 176196.766848570783623f, + 176224.084706156252651f, 176251.403622470854316f, 176278.723597432486713f, + 176306.044630959106144f, 176333.366722968727117f, 176360.689873379335040f, + 176388.014082108944422f, 176415.339349075540667f, 176442.665674197196495f, + 176469.993057391955517f, 176497.321498577890452f, 176524.650997673132224f, + 176551.981554595724447f, 176579.313169263798045f, 176606.645841595513048f, + 176633.979571509029483f, 176661.314358922478277f, 176688.650203754048562f, + 176715.987105921987677f, 176743.325065344426548f, 176770.664081939670723f, + 176798.004155625967542f, 176825.345286321506137f, 176852.687473944621161f, + 176880.030718413618160f, 176907.375019646773580f, 176934.720377562422073f, + 176962.066792078898288f, 176989.414263114595087f, 177016.762790587847121f, + 177044.112374417047249f, 177071.463014520617435f, 177098.814710816950537f, + 177126.167463224497624f, 177153.521271661738865f, 177180.876136047096225f, + 177208.232056299078977f, 177235.589032336196396f, 177262.947064076928655f, + 177290.306151439814130f, 177317.666294343420304f, 177345.027492706314661f, + 177372.389746447035577f, 177399.753055484208744f, 177427.117419736430747f, + 177454.482839122327277f, 177481.849313560524024f, 177509.216842969704885f, + 177536.585427268524654f, 177563.955066375696333f, 177591.325760209874716f, + 177618.697508689831011f, 177646.070311734249117f, 177673.444169261900242f, + 177700.819081191584701f, 177728.195047442015493f, 177755.572067932051141f, + 177782.950142580462852f, 177810.329271306109149f, 177837.709454027819447f, + 177865.090690664452268f, 177892.472981134895235f, 177919.856325358006870f, + 177947.240723252703901f, 177974.626174737961264f, 178002.012679732637480f, + 178029.400238155736588f, 178056.788849926204421f, 178084.178514963045018f, + 178111.569233185233315f, 178138.961004511802457f, 178166.353828861785587f, + 178193.747706154215848f, 178221.142636308155488f, 178248.538619242695859f, + 178275.935654876928311f, 178303.333743129944196f, 178330.732883920893073f, + 178358.133077168895397f, 178385.534322793100728f, 178412.936620712687727f, + 178440.339970846864162f, 178467.744373114808695f, 178495.149827435729094f, + 178522.556333728891332f, 178549.963891913532279f, 178577.372501908888808f, + 178604.782163634255994f, 178632.192877008958021f, 178659.604641952260863f, + 178687.017458383488702f, 178714.431326222023927f, 178741.846245387219824f, + 178769.262215798400575f, 178796.679237375006778f, 178824.097310036420822f, + 178851.516433702054201f, 178878.936608291318407f, 178906.357833723712247f, + 178933.780109918676317f, 178961.203436795709422f, 178988.627814274281263f, + 179016.053242273919750f, 179043.479720714123687f, 179070.907249514479190f, + 179098.335828594485065f, 179125.765457873785635f, 179153.196137271908810f, + 179180.627866708498914f, 179208.060646103142062f, 179235.494475375511684f, + 179262.929354445222998f, 179290.365283231949434f, 179317.802261655364418f, + 179345.240289635170484f, 179372.679367091099266f, 179400.119493942853296f, + 179427.560670110193314f, 179455.002895512850955f, 179482.446170070616063f, + 179509.890493703249376f, 179537.335866330598947f, 179564.782287872454617f, + 179592.229758248664439f, 179619.678277379076462f, 179647.127845183509635f, + 179674.578461581928423f, 179702.030126494151773f, 179729.482839840144152f, + 179756.936601539782714f, 179784.391411513031926f, 179811.847269679856254f, + 179839.304175960249268f, 179866.762130274117226f, 179894.221132541541010f, + 179921.681182682514191f, 179949.142280617059441f, 179976.604426265228540f, + 180004.067619547073264f, 180031.531860382703599f, 180058.997148692200426f, + 180086.463484395644628f, 180113.930867413204396f, 180141.399297664960613f, + 180168.868775071139680f, 180196.339299551851582f, 180223.810871027322719f, + 180251.283489417721285f, 180278.757154643302783f, 180306.231866624235408f, + 180333.707625280832872f, 180361.184430533292470f, 180388.662282301957021f, + 180416.141180507052923f, 180443.621125068922993f, 180471.102115907880943f, + 180498.584152944269590f, 180526.067236098460853f, 180553.551365290768445f, + 180581.036540441593388f, 180608.522761471365811f, 180636.010028300457634f, + 180663.498340849328088f, 180690.987699038407300f, 180718.478102788154501f, + 180745.969552019028924f, 180773.462046651518904f, 180800.955586606170982f, + 180828.450171803444391f, 180855.945802163914777f, 180883.442477608099580f, + 180910.940198056603549f, 180938.438963429944124f, 180965.938773648784263f, + 180993.439628633699613f, 181020.941528305294923f, 181048.444472584233154f, + 181075.948461391177261f, 181103.453494646761101f, 181130.959572271705838f, + 181158.466694186703535f, 181185.974860312475357f, 181213.484070569713367f, + 181240.994324879196938f, 181268.505623161647236f, 181296.017965337901842f, + 181323.531351328711025f, 181351.045781054854160f, 181378.561254437197931f, + 181406.077771396579919f, 181433.595331853808602f, 181461.113935729750665f, + 181488.633582945331000f, 181516.154273421416292f, 181543.676007078902330f, + 181571.198783838743111f, 181598.722603621863527f, 181626.247466349188471f, + 181653.773371941759251f, 181681.300320320500759f, 181708.828311406425200f, + 181736.357345120573882f, 181763.887421383929905f, 181791.418540117563680f, + 181818.950701242545620f, 181846.483904679946136f, 181874.018150350835640f, + 181901.553438176342752f, 181929.089768077566987f, 181956.627139975636965f, + 181984.165553791710408f, 182011.705009446974145f, 182039.245506862556795f, + 182066.787045959703391f, 182094.329626659600763f, 182121.873248883464839f, + 182149.417912552540656f, 182176.963617588102352f, 182204.510363911394961f, + 182232.058151443692623f, 182259.606980106298579f, 182287.156849820545176f, + 182314.707760507735657f, 182342.259712089231471f, 182369.812704486394068f, + 182397.366737620584900f, 182424.921811413165415f, 182452.477925785584375f, + 182480.035080659232335f, 182507.593275955528952f, 182535.152511595952092f, + 182562.712787501950515f, 182590.274103595002089f, 182617.836459796584677f, + 182645.399856028205249f, 182672.964292211399879f, 182700.529768267704640f, + 182728.096284118655603f, 182755.663839685817948f, 182783.232434890785953f, + 182810.802069655124797f, 182838.372743900486967f, 182865.944457548437640f, + 182893.517210520687513f, 182921.091002738830866f, 182948.665834124578396f, + 182976.241704599582590f, 183003.818614085554145f, 183031.396562504203757f, + 183058.975549777242122f, 183086.555575826438144f, 183114.136640573531622f, + 183141.718743940320564f, 183169.301885848544771f, 183196.886066220060457f, + 183224.471284976636525f, 183252.057542040129192f, 183279.644837332365569f, + 183307.233170775230974f, 183334.822542290581623f, 183362.412951800302835f, + 183390.004399226309033f, 183417.596884490514640f, 183445.190407514834078f, + 183472.784968221269082f, 183500.380566531734075f, 183527.977202368201688f, + 183555.574875652702758f, 183583.173586307239020f, 183610.773334253783105f, + 183638.374119414424058f, 183665.975941711192718f, 183693.578801066149026f, + 183721.182697401382029f, 183748.787630638980772f, 183776.393600701063406f, + 183804.000607509748079f, 183831.608650987152942f, 183859.217731055454351f, + 183886.827847636828665f, 183914.439000653452240f, 183942.051190027501434f, + 183969.664415681181708f, 183997.278677536756732f, 184024.893975516461069f, + 184052.510309542529285f, 184080.127679537225049f, 184107.746085422870237f, + 184135.365527121728519f, 184162.986004556121770f, 184190.607517648371868f, + 184218.230066320858896f, 184245.853650495904731f, 184273.478270095860353f, + 184301.103925043164054f, 184328.730615260195918f, 184356.358340669365134f, + 184383.987101193109993f, 184411.616896753868787f, 184439.247727274108911f, + 184466.879592676268658f, 184494.512492882873630f, 184522.146427816449432f, + 184549.781397399434354f, 184577.417401554441312f, 184605.054440203966806f, + 184632.692513270594645f, 184660.331620676879538f, 184687.971762345434399f, + 184715.612938198843040f, 184743.255148159718374f, 184770.898392150731524f, + 184798.542670094495406f, 184826.187981913681142f, 184853.834327530959854f, + 184881.481706869031768f, 184909.130119850597112f, 184936.779566398385214f, + 184964.430046435125405f, 184992.081559883547015f, 185019.734106666437583f, + 185047.387686706584645f, 185075.042299926717533f, 185102.697946249711094f, + 185130.354625598381972f, 185158.012337895517703f, 185185.671083063993137f, + 185213.330861026683124f, 185240.991671706462512f, 185268.653515026206151f, + 185296.316390908847097f, 185323.980299277289305f, 185351.645240054465830f, + 185379.311213163338834f, 185406.978218526870478f, 185434.646256068022922f, + 185462.315325709816534f, 185489.985427375242580f, 185517.656560987321427f, + 185545.328726469102548f, 185573.001923743606312f, 185600.676152733940398f, + 185628.351413363154279f, 185656.027705554384738f, 185683.705029230652144f, + 185711.383384315180592f, 185739.062770731048658f, 185766.743188401393127f, + 185794.424637249438092f, 185822.107117198320339f, 185849.790628171234857f, + 185877.475170091405744f, 185905.160742882027989f, 185932.847346466383897f, + 185960.534980767697562f, 185988.223645709222183f, 186015.913341214269167f, + 186043.604067206120817f, 186071.295823608059436f, 186098.988610343454638f, + 186126.682427335588727f, 186154.377274507860420f, 186182.073151783610228f, + 186209.770059086207766f, 186237.467996339080855f, 186265.166963465628214f, + 186292.866960389248561f, 186320.567987033398822f, 186348.270043321506819f, + 186375.973129177087685f, 186403.677244523569243f, 186431.382389284466626f, + 186459.088563383265864f, 186486.795766743540298f, 186514.503999288775958f, + 186542.213260942546185f, 186569.923551628395217f, 186597.634871269954601f, + 186625.347219790739473f, 186653.060597114410484f, 186680.775003164570080f, + 186708.490437864878913f, 186736.206901138939429f, 186763.924392910441384f, + 186791.642913103074534f, 186819.362461640528636f, 186847.083038446493447f, + 186874.804643444687827f, 186902.527276558859739f, 186930.250937712757150f, + 186957.975626830157125f, 186985.701343834778527f, 187013.428088650485734f, + 187041.155861201026710f, 187068.884661410265835f, 187096.614489202009281f, + 187124.345344500121428f, 187152.077227228437550f, 187179.810137310851132f, +}; + +const FLOAT64 iusace_mdst_fcoeff_long_sin[] = {-0.000000f, -0.000000f, 0.500000f, 0.000000f, + -0.500000f, 0.000000f, 0.000000f}; +const FLOAT64 iusace_mdst_fcoeff_long_kbd[] = {0.091497f, -0.000000f, 0.581427f, 0.000000f, + -0.581427f, 0.000000f, -0.091497f}; +const FLOAT64 iusace_mdst_fcoeff_long_sin_kbd[] = {0.045748f, 0.057238f, 0.540714f, 0.000000f, + -0.540714f, -0.057238f, -0.045748f}; +const FLOAT64 iusace_mdst_fcoeff_long_kbd_sin[] = {0.045748f, -0.057238f, 0.540714f, 0.000000f, + -0.540714f, 0.057238f, -0.045748f}; + +const FLOAT64 *const iusace_mdst_fcoeff_longshort_curr[2][2] = { + {iusace_mdst_fcoeff_long_sin, iusace_mdst_fcoeff_long_sin_kbd}, + {iusace_mdst_fcoeff_long_kbd_sin, iusace_mdst_fcoeff_long_kbd}}; + +const FLOAT64 iusace_mdst_fcoeff_start_sin[] = {0.102658f, 0.103791f, 0.567149f, 0.000000f, + -0.567149f, -0.103791f, -0.102658f}; +const FLOAT64 iusace_mdst_fcoeff_start_kbd[] = {0.150512f, 0.047969f, 0.608574f, 0.000000f, + -0.608574f, -0.047969f, -0.150512f}; +const FLOAT64 iusace_mdst_fcoeff_start_sin_kbd[] = {0.104763f, 0.105207f, 0.567861f, 0.000000f, + -0.567861f, -0.105207f, -0.104763f}; +const FLOAT64 iusace_mdst_fcoeff_start_kbd_sin[] = {0.148406f, 0.046553f, 0.607863f, 0.000000f, + -0.607863f, -0.046553f, -0.148406f}; + +const FLOAT64 *const iusace_mdst_fcoeff_start_curr[2][2] = { + {iusace_mdst_fcoeff_start_sin, iusace_mdst_fcoeff_start_sin_kbd}, + {iusace_mdst_fcoeff_start_kbd_sin, iusace_mdst_fcoeff_start_kbd}}; + +const FLOAT64 iusace_mdst_fcoeff_stop_sin[] = {0.102658f, -0.103791f, 0.567149f, 0.000000f, + -0.567149f, 0.103791f, -0.102658f}; +const FLOAT64 iusace_mdst_fcoeff_stop_kbd[] = {0.150512f, -0.047969f, 0.608574f, 0.000000f, + -0.608574f, 0.047969f, -0.150512f}; +const FLOAT64 iusace_mdst_fcoeff_stop_sin_kbd[] = {0.148406f, -0.046553f, 0.607863f, 0.000000f, + -0.607863f, 0.046553f, -0.148406f}; +const FLOAT64 iusace_mdst_fcoeff_stop_kbd_sin[] = {0.104763f, -0.105207f, 0.567861f, 0.000000f, + -0.567861f, 0.105207f, -0.104763f}; + +const FLOAT64 *const iusace_mdst_fcoeff_stop_cur[2][2] = { + {iusace_mdst_fcoeff_stop_sin, iusace_mdst_fcoeff_stop_sin_kbd}, + {iusace_mdst_fcoeff_stop_kbd_sin, iusace_mdst_fcoeff_stop_kbd}}; + +const FLOAT64 iusace_mdst_fcoeff_stopstart_sin[] = {0.205316f, -0.000000f, 0.634298f, 0.000000f, + -0.634298f, 0.000000f, -0.205316f}; +const FLOAT64 iusace_mdst_fcoeff_stopstart_kbd[] = {0.209526f, -0.000000f, 0.635722f, 0.000000f, + -0.635722f, 0.000000f, -0.209526f}; +const FLOAT64 iusace_mdst_fcoeff_stopstart_sin_kbd[] = { + 0.207421f, 0.001416f, 0.635010f, 0.000000f, -0.635010f, -0.001416f, -0.207421f}; +const FLOAT64 iusace_mdst_fcoeff_stopstart_kbd_sin[] = { + 0.207421f, -0.001416f, 0.635010f, 0.000000f, -0.635010f, 0.001416f, -0.207421f}; + +const FLOAT64 *const iusace_mdst_fcoeff_stopstart_cur[2][2] = { + {iusace_mdst_fcoeff_stopstart_sin, iusace_mdst_fcoeff_stopstart_sin_kbd}, + {iusace_mdst_fcoeff_stopstart_kbd_sin, iusace_mdst_fcoeff_stopstart_kbd}}; + +const FLOAT64 iusace_mdst_fcoeff_l_s_start_left_sin[] = { + -0.000000f, 0.106103f, 0.250000f, 0.318310f, 0.250000f, 0.106103f, -0.000000f}; +const FLOAT64 iusace_mdst_fcoeff_l_s_start_left_kbd[] = { + 0.059509f, 0.123714f, 0.186579f, 0.213077f, 0.186579f, 0.123714f, 0.059509f}; + +const FLOAT64 iusace_mdst_fcoeff_stop_stopstart_left_sin[] = { + 0.038498f, 0.039212f, 0.039645f, 0.039790f, 0.039645f, 0.039212f, 0.038498f}; +const FLOAT64 iusace_mdst_fcoeff_stop_stopstart_left_kbd[] = { + 0.026142f, 0.026413f, 0.026577f, 0.026631f, 0.026577f, 0.026413f, 0.026142f}; + +const FLOAT64 *const iusace_mdst_fcoeff_l_s_start_left_prev[2] = { + iusace_mdst_fcoeff_l_s_start_left_sin, iusace_mdst_fcoeff_l_s_start_left_kbd}; + +const FLOAT64 *const iusace_mdst_fcoeff_stop_stopstart_left_prev[2] = { + iusace_mdst_fcoeff_stop_stopstart_left_sin, iusace_mdst_fcoeff_stop_stopstart_left_kbd}; + +const FLOAT32 ia_rad_3_fft_twiddle_re[1155] = { + 1.00000000000000000000f, 1.00000000000000000000f, 1.00000000000000000000f, + 1.00000000000000000000f, 0.99986613790956180000f, 0.99946458747636568000f, + 1.00000000000000000000f, 0.99946458747636568000f, 0.99785892323860348000f, + 1.00000000000000000000f, 0.99879545620517241000f, 0.99518472667219693000f, + 1.00000000000000000000f, 0.99785892323860348000f, 0.99144486137381038000f, + 1.00000000000000000000f, 0.99665523930918032000f, 0.98664333208487898000f, + 1.00000000000000000000f, 0.99518472667219693000f, 0.98078528040323043000f, + 1.00000000000000000000f, 0.99344777901944437000f, 0.97387697927733363000f, + 1.00000000000000000000f, 0.99144486137381038000f, 0.96592582628906831000f, + 1.00000000000000000000f, 0.98917650996478101000f, 0.95694033573220882000f, + 1.00000000000000000000f, 0.98664333208487898000f, 0.94693012949510569000f, + 1.00000000000000000000f, 0.98384600592707738000f, 0.93590592675732576000f, + 1.00000000000000000000f, 0.98078528040323043000f, 0.92387953251128674000f, + 1.00000000000000000000f, 0.97746197494357190000f, 0.91086382492117579000f, + 1.00000000000000000000f, 0.97387697927733363000f, 0.89687274153268837000f, + 1.00000000000000000000f, 0.97003125319454397000f, 0.88192126434835505000f, + 1.00000000000000000000f, 0.96592582628906831000f, 0.86602540378443871000f, + 1.00000000000000000000f, 0.96156179768296191000f, 0.84920218152657889000f, + 1.00000000000000000000f, 0.95694033573220882000f, 0.83146961230254524000f, + 1.00000000000000000000f, 0.95206267771392428000f, 0.81284668459161524000f, + 1.00000000000000000000f, 0.94693012949510569000f, 0.79335334029123517000f, + 1.00000000000000000000f, 0.94154406518302081000f, 0.77301045336273699000f, + 1.00000000000000000000f, 0.93590592675732576000f, 0.75183980747897738000f, + 1.00000000000000000000f, 0.93001722368401218000f, 0.72986407269783571000f, + 1.00000000000000000000f, 0.92387953251128674000f, 0.70710678118654757000f, + 1.00000000000000000000f, 0.91749449644749126000f, 0.68359230202287125000f, + 1.00000000000000000000f, 0.91086382492117579000f, 0.65934581510006884000f, + 1.00000000000000000000f, 0.90398929312344334000f, 0.63439328416364549000f, + 1.00000000000000000000f, 0.89687274153268837000f, 0.60876142900872066000f, + 1.00000000000000000000f, 0.88951607542185607000f, 0.58247769686780215000f, + 1.00000000000000000000f, 0.88192126434835505000f, 0.55557023301960240000f, + 1.00000000000000000000f, 0.87409034162675892000f, 0.52806785065036810000f, + 1.00000000000000000000f, 0.86602540378443871000f, 0.50000000000000011000f, + 1.00000000000000000000f, 0.85772861000027201000f, 0.47139673682599759000f, + 1.00000000000000000000f, 0.84920218152657889000f, 0.44228869021900125000f, + 1.00000000000000000000f, 0.84044840109443797000f, 0.41270702980439472000f, + 1.00000000000000000000f, 0.83146961230254524000f, 0.38268343236508984000f, + 1.00000000000000000000f, 0.82226821898977509000f, 0.35225004792123360000f, + 1.00000000000000000000f, 0.81284668459161524000f, 0.32143946530316170000f, + 1.00000000000000000000f, 0.80320753148064494000f, 0.29028467725446250000f, + 1.00000000000000000000f, 0.79335334029123517000f, 0.25881904510252074000f, + 1.00000000000000000000f, 0.78328674922865049000f, 0.22707626303437345000f, + 1.00000000000000000000f, 0.77301045336273699000f, 0.19509032201612833000f, + 1.00000000000000000000f, 0.76252720390638817000f, 0.16289547339458882000f, + 1.00000000000000000000f, 0.75183980747897738000f, 0.13052619222005171000f, + 1.00000000000000000000f, 0.74095112535495911000f, 0.09801714032956054800f, + 1.00000000000000000000f, 0.72986407269783571000f, 0.06540312923014327000f, + 1.00000000000000000000f, 0.71858161777969809000f, 0.03271908282177616500f, + 1.00000000000000000000f, 0.70710678118654757000f, 0.00000000000000006123f, + 1.00000000000000000000f, 0.69544263500961168000f, -0.03271908282177604000f, + 1.00000000000000000000f, 0.68359230202287125000f, -0.06540312923014314500f, + 1.00000000000000000000f, 0.67155895484701844000f, -0.09801714032956042300f, + 1.00000000000000000000f, 0.65934581510006884000f, -0.13052619222005160000f, + 1.00000000000000000000f, 0.64695615253485739000f, -0.16289547339458871000f, + 1.00000000000000000000f, 0.63439328416364549000f, -0.19509032201612819000f, + 1.00000000000000000000f, 0.62166057337007741000f, -0.22707626303437331000f, + 1.00000000000000000000f, 0.60876142900872066000f, -0.25881904510252063000f, + 1.00000000000000000000f, 0.59569930449243347000f, -0.29028467725446216000f, + 1.00000000000000000000f, 0.58247769686780215000f, -0.32143946530316159000f, + 1.00000000000000000000f, 0.56910014587889823000f, -0.35225004792123349000f, + 1.00000000000000000000f, 0.55557023301960240000f, -0.38268343236508950000f, + 1.00000000000000000000f, 0.54189158057475173000f, -0.41270702980439461000f, + 1.00000000000000000000f, 0.52806785065036810000f, -0.44228869021900113000f, + 1.00000000000000000000f, 0.51410274419322166000f, -0.47139673682599770000f, + 1.00000000000000000000f, 0.50000000000000011000f, -0.49999999999999978000f, + 1.00000000000000000000f, 0.48576339371634009000f, -0.52806785065036799000f, + 1.00000000000000000000f, 0.47139673682599759000f, -0.55557023301960229000f, + 1.00000000000000000000f, 0.45690387563042073000f, -0.58247769686780204000f, + 1.00000000000000000000f, 0.44228869021900125000f, -0.60876142900872066000f, + 1.00000000000000000000f, 0.42755509343028220000f, -0.63439328416364538000f, + 1.00000000000000000000f, 0.41270702980439472000f, -0.65934581510006884000f, + 1.00000000000000000000f, 0.39774847452701095000f, -0.68359230202287136000f, + 1.00000000000000000000f, 0.38268343236508984000f, -0.70710678118654746000f, + 1.00000000000000000000f, 0.36751593659470372000f, -0.72986407269783538000f, + 1.00000000000000000000f, 0.35225004792123360000f, -0.75183980747897727000f, + 1.00000000000000000000f, 0.33688985339222005000f, -0.77301045336273699000f, + 1.00000000000000000000f, 0.32143946530316170000f, -0.79335334029123505000f, + 1.00000000000000000000f, 0.30590302009655351000f, -0.81284668459161513000f, + 1.00000000000000000000f, 0.29028467725446250000f, -0.83146961230254501000f, + 1.00000000000000000000f, 0.27458861818493241000f, -0.84920218152657878000f, + 1.00000000000000000000f, 0.25881904510252074000f, -0.86602540378443871000f, + 1.00000000000000000000f, 0.24298017990326398000f, -0.88192126434835494000f, + 1.00000000000000000000f, 0.22707626303437345000f, -0.89687274153268814000f, + 1.00000000000000000000f, 0.21111155235896509000f, -0.91086382492117590000f, + 1.00000000000000000000f, 0.19509032201612833000f, -0.92387953251128674000f, + 1.00000000000000000000f, 0.17901686127663263000f, -0.93590592675732576000f, + 1.00000000000000000000f, 0.16289547339458882000f, -0.94693012949510558000f, + 1.00000000000000000000f, 0.14673047445536197000f, -0.95694033573220871000f, + 1.00000000000000000000f, 0.13052619222005171000f, -0.96592582628906820000f, + 1.00000000000000000000f, 0.11428696496684644000f, -0.97387697927733363000f, + 1.00000000000000000000f, 0.09801714032956054800f, -0.98078528040323043000f, + 1.00000000000000000000f, 0.08172107413366830300f, -0.98664333208487898000f, + 1.00000000000000000000f, 0.06540312923014327000f, -0.99144486137381038000f, + 1.00000000000000000000f, 0.04906767432741812600f, -0.99518472667219682000f, + 1.00000000000000000000f, 0.03271908282177616500f, -0.99785892323860348000f, + 1.00000000000000000000f, 0.01636173162648671400f, -0.99946458747636568000f, + 1.00000000000000000000f, 0.00000000000000006123f, -1.00000000000000000000f, + 1.00000000000000000000f, -0.01636173162648658900f, -0.99946458747636568000f, + 1.00000000000000000000f, -0.03271908282177604000f, -0.99785892323860348000f, + 1.00000000000000000000f, -0.04906767432741800800f, -0.99518472667219693000f, + 1.00000000000000000000f, -0.06540312923014314500f, -0.99144486137381038000f, + 1.00000000000000000000f, -0.08172107413366817800f, -0.98664333208487898000f, + 1.00000000000000000000f, -0.09801714032956042300f, -0.98078528040323054000f, + 1.00000000000000000000f, -0.11428696496684632000f, -0.97387697927733363000f, + 1.00000000000000000000f, -0.13052619222005160000f, -0.96592582628906831000f, + 1.00000000000000000000f, -0.14673047445536186000f, -0.95694033573220882000f, + 1.00000000000000000000f, -0.16289547339458871000f, -0.94693012949510569000f, + 1.00000000000000000000f, -0.17901686127663252000f, -0.93590592675732587000f, + 1.00000000000000000000f, -0.19509032201612819000f, -0.92387953251128685000f, + 1.00000000000000000000f, -0.21111155235896498000f, -0.91086382492117601000f, + 1.00000000000000000000f, -0.22707626303437331000f, -0.89687274153268826000f, + 1.00000000000000000000f, -0.24298017990326387000f, -0.88192126434835505000f, + 1.00000000000000000000f, -0.25881904510252063000f, -0.86602540378443882000f, + 1.00000000000000000000f, -0.27458861818493230000f, -0.84920218152657889000f, + 1.00000000000000000000f, -0.29028467725446216000f, -0.83146961230254546000f, + 1.00000000000000000000f, -0.30590302009655357000f, -0.81284668459161502000f, + 1.00000000000000000000f, -0.32143946530316159000f, -0.79335334029123517000f, + 1.00000000000000000000f, -0.33688985339221994000f, -0.77301045336273710000f, + 1.00000000000000000000f, -0.35225004792123349000f, -0.75183980747897750000f, + 1.00000000000000000000f, -0.36751593659470339000f, -0.72986407269783593000f, + 1.00000000000000000000f, -0.38268343236508950000f, -0.70710678118654791000f, + 1.00000000000000000000f, -0.39774847452701106000f, -0.68359230202287125000f, + 1.00000000000000000000f, -0.41270702980439461000f, -0.65934581510006907000f, + 1.00000000000000000000f, -0.42755509343028186000f, -0.63439328416364593000f, + 1.00000000000000000000f, -0.44228869021900113000f, -0.60876142900872088000f, + 1.00000000000000000000f, -0.45690387563042062000f, -0.58247769686780226000f, + 1.00000000000000000000f, -0.47139673682599770000f, -0.55557023301960218000f, + 1.00000000000000000000f, -0.48576339371634014000f, -0.52806785065036776000f, + 1.00000000000000000000f, -0.49999999999999978000f, -0.50000000000000044000f, + 1.00000000000000000000f, -0.51410274419322166000f, -0.47139673682599786000f, + 1.00000000000000000000f, -0.52806785065036799000f, -0.44228869021900136000f, + 1.00000000000000000000f, -0.54189158057475173000f, -0.41270702980439467000f, + 1.00000000000000000000f, -0.55557023301960229000f, -0.38268343236508950000f, + 1.00000000000000000000f, -0.56910014587889801000f, -0.35225004792123393000f, + 1.00000000000000000000f, -0.58247769686780204000f, -0.32143946530316181000f, + 1.00000000000000000000f, -0.59569930449243336000f, -0.29028467725446244000f, + 1.00000000000000000000f, -0.60876142900872066000f, -0.25881904510252063000f, + 1.00000000000000000000f, -0.62166057337007752000f, -0.22707626303437292000f, + 1.00000000000000000000f, -0.63439328416364538000f, -0.19509032201612866000f, + 1.00000000000000000000f, -0.64695615253485728000f, -0.16289547339458896000f, + 1.00000000000000000000f, -0.65934581510006884000f, -0.13052619222005163000f, + 1.00000000000000000000f, -0.67155895484701811000f, -0.09801714032956133900f, + 1.00000000000000000000f, -0.68359230202287136000f, -0.06540312923014272900f, + 1.00000000000000000000f, -0.69544263500961156000f, -0.03271908282177651100f, + 1.00000000000000000000f, -0.70710678118654746000f, -0.00000000000000018369f, + 1.00000000000000000000f, -0.71858161777969809000f, 0.03271908282177614400f, + 1.00000000000000000000f, -0.72986407269783538000f, 0.06540312923014236800f, + 1.00000000000000000000f, -0.74095112535495922000f, 0.09801714032956096400f, + 1.00000000000000000000f, -0.75183980747897727000f, 0.13052619222005127000f, + 1.00000000000000000000f, -0.76252720390638806000f, 0.16289547339458860000f, + 1.00000000000000000000f, -0.77301045336273699000f, 0.19509032201612830000f, + 1.00000000000000000000f, -0.78328674922865016000f, 0.22707626303437256000f, + 1.00000000000000000000f, -0.79335334029123505000f, 0.25881904510252030000f, + 1.00000000000000000000f, -0.80320753148064483000f, 0.29028467725446205000f, + 1.00000000000000000000f, -0.81284668459161513000f, 0.32143946530316148000f, + 1.00000000000000000000f, -0.82226821898977509000f, 0.35225004792123354000f, + 1.00000000000000000000f, -0.83146961230254501000f, 0.38268343236508917000f, + 1.00000000000000000000f, -0.84044840109443786000f, 0.41270702980439433000f, + 1.00000000000000000000f, -0.84920218152657878000f, 0.44228869021900102000f, + 1.00000000000000000000f, -0.85772861000027201000f, 0.47139673682599759000f, + 1.00000000000000000000f, -0.86602540378443871000f, 0.50000000000000011000f, + 1.00000000000000000000f, -0.87409034162675869000f, 0.52806785065036743000f, + 1.00000000000000000000f, -0.88192126434835494000f, 0.55557023301960184000f, + 1.00000000000000000000f, -0.88951607542185596000f, 0.58247769686780193000f, + 1.00000000000000000000f, -0.89687274153268814000f, 0.60876142900871988000f, + 1.00000000000000000000f, -0.90398929312344312000f, 0.63439328416364493000f, + 1.00000000000000000000f, -0.91086382492117590000f, 0.65934581510006907000f, + 1.00000000000000000000f, -0.91749449644749137000f, 0.68359230202287169000f, + 1.00000000000000000000f, -0.92387953251128674000f, 0.70710678118654735000f, + 1.00000000000000000000f, -0.93001722368401207000f, 0.72986407269783560000f, + 1.00000000000000000000f, -0.93590592675732576000f, 0.75183980747897750000f, + 1.00000000000000000000f, -0.94154406518302070000f, 0.77301045336273666000f, + 1.00000000000000000000f, -0.94693012949510558000f, 0.79335334029123494000f, + 1.00000000000000000000f, -0.95206267771392428000f, 0.81284668459161513000f, + 1.00000000000000000000f, -0.95694033573220871000f, 0.83146961230254479000f, + 1.00000000000000000000f, -0.96156179768296191000f, 0.84920218152657856000f, + 1.00000000000000000000f, -0.96592582628906820000f, 0.86602540378443837000f, + 1.00000000000000000000f, -0.97003125319454409000f, 0.88192126434835527000f, + 1.00000000000000000000f, -0.97387697927733363000f, 0.89687274153268826000f, + 1.00000000000000000000f, -0.97746197494357190000f, 0.91086382492117579000f, + 1.00000000000000000000f, -0.98078528040323043000f, 0.92387953251128685000f, + 1.00000000000000000000f, -0.98384600592707738000f, 0.93590592675732553000f, + 1.00000000000000000000f, -0.98664333208487898000f, 0.94693012949510558000f, + 1.00000000000000000000f, -0.98917650996478101000f, 0.95694033573220882000f, + 1.00000000000000000000f, -0.99144486137381038000f, 0.96592582628906809000f, + 1.00000000000000000000f, -0.99344777901944437000f, 0.97387697927733352000f, + 1.00000000000000000000f, -0.99518472667219682000f, 0.98078528040323032000f, + 1.00000000000000000000f, -0.99665523930918032000f, 0.98664333208487909000f, + 1.00000000000000000000f, -0.99785892323860348000f, 0.99144486137381038000f, + 1.00000000000000000000f, -0.99879545620517241000f, 0.99518472667219693000f, + 1.00000000000000000000f, -0.99946458747636568000f, 0.99785892323860348000f, + 1.00000000000000000000f, -0.99986613790956180000f, 0.99946458747636568000f, + 1.00000000000000000000f, -1.00000000000000000000f, 1.00000000000000000000f, + 1.00000000000000000000f, -0.99986613790956180000f, 0.99946458747636568000f, + 1.00000000000000000000f, -0.99946458747636568000f, 0.99785892323860359000f, + 1.00000000000000000000f, -0.99879545620517241000f, 0.99518472667219693000f, + 1.00000000000000000000f, -0.99785892323860348000f, 0.99144486137381049000f, + 1.00000000000000000000f, -0.99665523930918032000f, 0.98664333208487920000f, + 1.00000000000000000000f, -0.99518472667219693000f, 0.98078528040323043000f, + 1.00000000000000000000f, -0.99344777901944437000f, 0.97387697927733363000f, + 1.00000000000000000000f, -0.99144486137381038000f, 0.96592582628906820000f, + 1.00000000000000000000f, -0.98917650996478101000f, 0.95694033573220894000f, + 1.00000000000000000000f, -0.98664333208487898000f, 0.94693012949510569000f, + 1.00000000000000000000f, -0.98384600592707738000f, 0.93590592675732565000f, + 1.00000000000000000000f, -0.98078528040323054000f, 0.92387953251128707000f, + 1.00000000000000000000f, -0.97746197494357190000f, 0.91086382492117601000f, + 1.00000000000000000000f, -0.97387697927733363000f, 0.89687274153268848000f, + 1.00000000000000000000f, -0.97003125319454409000f, 0.88192126434835549000f, + 1.00000000000000000000f, -0.96592582628906831000f, 0.86602540378443860000f, + 1.00000000000000000000f, -0.96156179768296191000f, 0.84920218152657878000f, + 1.00000000000000000000f, -0.95694033573220882000f, 0.83146961230254501000f, + 1.00000000000000000000f, -0.95206267771392428000f, 0.81284668459161535000f, + 1.00000000000000000000f, -0.94693012949510569000f, 0.79335334029123528000f, + 1.00000000000000000000f, -0.94154406518302081000f, 0.77301045336273688000f, + 1.00000000000000000000f, -0.93590592675732587000f, 0.75183980747897783000f, + 1.00000000000000000000f, -0.93001722368401218000f, 0.72986407269783593000f, + 1.00000000000000000000f, -0.92387953251128685000f, 0.70710678118654768000f, + 1.00000000000000000000f, -0.91749449644749148000f, 0.68359230202287202000f, + 1.00000000000000000000f, -0.91086382492117601000f, 0.65934581510006951000f, + 1.00000000000000000000f, -0.90398929312344323000f, 0.63439328416364527000f, + 1.00000000000000000000f, -0.89687274153268826000f, 0.60876142900872032000f, + 1.00000000000000000000f, -0.88951607542185607000f, 0.58247769686780237000f, + 1.00000000000000000000f, -0.88192126434835505000f, 0.55557023301960229000f, + 1.00000000000000000000f, -0.87409034162675880000f, 0.52806785065036788000f, + 1.00000000000000000000f, -0.86602540378443882000f, 0.50000000000000056000f, + 1.00000000000000000000f, -0.85772861000027212000f, 0.47139673682599798000f, + 1.00000000000000000000f, -0.84920218152657889000f, 0.44228869021900147000f, + 1.00000000000000000000f, -0.84044840109443830000f, 0.41270702980439555000f, + 1.00000000000000000000f, -0.83146961230254546000f, 0.38268343236509045000f, + 1.00000000000000000000f, -0.82226821898977531000f, 0.35225004792123404000f, + 1.00000000000000000000f, -0.81284668459161502000f, 0.32143946530316109000f, + 1.00000000000000000000f, -0.80320753148064494000f, 0.29028467725446255000f, + 1.00000000000000000000f, -0.79335334029123517000f, 0.25881904510252074000f, + 1.00000000000000000000f, -0.78328674922865027000f, 0.22707626303437303000f, + 1.00000000000000000000f, -0.77301045336273710000f, 0.19509032201612878000f, + 1.00000000000000000000f, -0.76252720390638817000f, 0.16289547339458907000f, + 1.00000000000000000000f, -0.75183980747897750000f, 0.13052619222005174000f, + 1.00000000000000000000f, -0.74095112535495933000f, 0.09801714032956145000f, + 1.00000000000000000000f, -0.72986407269783593000f, 0.06540312923014374200f, + 1.00000000000000000000f, -0.71858161777969820000f, 0.03271908282177662900f, + 1.00000000000000000000f, -0.70710678118654791000f, 0.00000000000000119433f, + 1.00000000000000000000f, -0.69544263500961168000f, -0.03271908282177601900f, + 1.00000000000000000000f, -0.68359230202287125000f, -0.06540312923014313100f, + 1.00000000000000000000f, -0.67155895484701833000f, -0.09801714032956084000f, + 1.00000000000000000000f, -0.65934581510006907000f, -0.13052619222005113000f, + 1.00000000000000000000f, -0.64695615253485750000f, -0.16289547339458846000f, + 1.00000000000000000000f, -0.63439328416364593000f, -0.19509032201612730000f, + 1.00000000000000000000f, -0.62166057337007741000f, -0.22707626303437331000f, + 1.00000000000000000000f, -0.60876142900872088000f, -0.25881904510252018000f, + 1.00000000000000000000f, -0.59569930449243391000f, -0.29028467725446111000f, + 1.00000000000000000000f, -0.58247769686780226000f, -0.32143946530316136000f, + 1.00000000000000000000f, -0.56910014587889790000f, -0.35225004792123427000f, + 1.00000000000000000000f, -0.55557023301960218000f, -0.38268343236508989000f, + 1.00000000000000000000f, -0.54189158057475195000f, -0.41270702980439422000f, + 1.00000000000000000000f, -0.52806785065036776000f, -0.44228869021900175000f, + 1.00000000000000000000f, -0.51410274419322177000f, -0.47139673682599748000f, + 1.00000000000000000000f, -0.50000000000000044000f, -0.49999999999999922000f, + 1.00000000000000000000f, -0.48576339371633998000f, -0.52806785065036810000f, + 1.00000000000000000000f, -0.47139673682599786000f, -0.55557023301960173000f, + 1.00000000000000000000f, -0.45690387563042123000f, -0.58247769686780115000f, + 1.00000000000000000000f, -0.44228869021900136000f, -0.60876142900872054000f, + 1.00000000000000000000f, -0.42755509343028247000f, -0.63439328416364482000f, + 1.00000000000000000000f, -0.41270702980439467000f, -0.65934581510006895000f, + 1.00000000000000000000f, -0.39774847452701129000f, -0.68359230202287091000f, + 1.00000000000000000000f, -0.38268343236508950000f, -0.70710678118654791000f, + 1.00000000000000000000f, -0.36751593659470366000f, -0.72986407269783560000f, + 1.00000000000000000000f, -0.35225004792123393000f, -0.75183980747897683000f, + 1.00000000000000000000f, -0.33688985339221994000f, -0.77301045336273710000f, + 1.00000000000000000000f, -0.32143946530316181000f, -0.79335334029123483000f, + 1.00000000000000000000f, -0.30590302009655401000f, -0.81284668459161447000f, + 1.00000000000000000000f, -0.29028467725446244000f, -0.83146961230254512000f, + 1.00000000000000000000f, -0.27458861818493274000f, -0.84920218152657845000f, + 1.00000000000000000000f, -0.25881904510252063000f, -0.86602540378443882000f, + 1.00000000000000000000f, -0.24298017990326412000f, -0.88192126434835483000f, + 1.00000000000000000000f, -0.22707626303437292000f, -0.89687274153268859000f, + 1.00000000000000000000f, -0.21111155235896520000f, -0.91086382492117579000f, + 1.00000000000000000000f, -0.19509032201612866000f, -0.92387953251128641000f, + 1.00000000000000000000f, -0.17901686127663255000f, -0.93590592675732576000f, + 1.00000000000000000000f, -0.16289547339458896000f, -0.94693012949510558000f, + 1.00000000000000000000f, -0.14673047445536230000f, -0.95694033573220849000f, + 1.00000000000000000000f, -0.13052619222005163000f, -0.96592582628906831000f, + 1.00000000000000000000f, -0.11428696496684677000f, -0.97387697927733352000f, + 1.00000000000000000000f, -0.09801714032956133900f, -0.98078528040323021000f, + 1.00000000000000000000f, -0.08172107413366842800f, -0.98664333208487898000f, + 1.00000000000000000000f, -0.06540312923014272900f, -0.99144486137381049000f, + 1.00000000000000000000f, -0.04906767432741802900f, -0.99518472667219693000f, + 1.00000000000000000000f, -0.03271908282177651100f, -0.99785892323860348000f, + 1.00000000000000000000f, -0.01636173162648661300f, -0.99946458747636568000f, + 1.00000000000000000000f, -0.00000000000000018369f, -1.00000000000000000000f, + 1.00000000000000000000f, 0.01636173162648624600f, -0.99946458747636568000f, + 1.00000000000000000000f, 0.03271908282177614400f, -0.99785892323860348000f, + 1.00000000000000000000f, 0.04906767432741766100f, -0.99518472667219693000f, + 1.00000000000000000000f, 0.06540312923014236800f, -0.99144486137381060000f, + 1.00000000000000000000f, 0.08172107413366805400f, -0.98664333208487909000f, + 1.00000000000000000000f, 0.09801714032956096400f, -0.98078528040323032000f, + 1.00000000000000000000f, 0.11428696496684641000f, -0.97387697927733363000f, + 1.00000000000000000000f, 0.13052619222005127000f, -0.96592582628906842000f, + 1.00000000000000000000f, 0.14673047445536194000f, -0.95694033573220871000f, + 1.00000000000000000000f, 0.16289547339458860000f, -0.94693012949510580000f, + 1.00000000000000000000f, 0.17901686127663219000f, -0.93590592675732609000f, + 1.00000000000000000000f, 0.19509032201612830000f, -0.92387953251128674000f, + 1.00000000000000000000f, 0.21111155235896484000f, -0.91086382492117612000f, + 1.00000000000000000000f, 0.22707626303437256000f, -0.89687274153268892000f, + 1.00000000000000000000f, 0.24298017990326376000f, -0.88192126434835516000f, + 1.00000000000000000000f, 0.25881904510252030000f, -0.86602540378443915000f, + 1.00000000000000000000f, 0.27458861818493241000f, -0.84920218152657889000f, + 1.00000000000000000000f, 0.29028467725446205000f, -0.83146961230254557000f, + 1.00000000000000000000f, 0.30590302009655368000f, -0.81284668459161491000f, + 1.00000000000000000000f, 0.32143946530316148000f, -0.79335334029123528000f, + 1.00000000000000000000f, 0.33688985339221961000f, -0.77301045336273755000f, + 1.00000000000000000000f, 0.35225004792123354000f, -0.75183980747897727000f, + 1.00000000000000000000f, 0.36751593659470327000f, -0.72986407269783604000f, + 1.00000000000000000000f, 0.38268343236508917000f, -0.70710678118654846000f, + 1.00000000000000000000f, 0.39774847452701095000f, -0.68359230202287147000f, + 1.00000000000000000000f, 0.41270702980439433000f, -0.65934581510006951000f, + 1.00000000000000000000f, 0.42755509343028214000f, -0.63439328416364538000f, + 1.00000000000000000000f, 0.44228869021900102000f, -0.60876142900872110000f, + 1.00000000000000000000f, 0.45690387563042090000f, -0.58247769686780171000f, + 1.00000000000000000000f, 0.47139673682599759000f, -0.55557023301960240000f, + 1.00000000000000000000f, 0.48576339371633964000f, -0.52806785065036876000f, + 1.00000000000000000000f, 0.50000000000000011000f, -0.49999999999999983000f, + 1.00000000000000000000f, 0.51410274419322155000f, -0.47139673682599809000f, + 1.00000000000000000000f, 0.52806785065036743000f, -0.44228869021900236000f, + 1.00000000000000000000f, 0.54189158057475162000f, -0.41270702980439489000f, + 1.00000000000000000000f, 0.55557023301960184000f, -0.38268343236509056000f, + 1.00000000000000000000f, 0.56910014587889757000f, -0.35225004792123499000f, + 1.00000000000000000000f, 0.58247769686780193000f, -0.32143946530316203000f, + 1.00000000000000000000f, 0.59569930449243358000f, -0.29028467725446183000f, + 1.00000000000000000000f, 0.60876142900871988000f, -0.25881904510252257000f, + 1.00000000000000000000f, 0.62166057337007707000f, -0.22707626303437400000f, + 1.00000000000000000000f, 0.63439328416364493000f, -0.19509032201612977000f, + 1.00000000000000000000f, 0.64695615253485717000f, -0.16289547339458918000f, + 1.00000000000000000000f, 0.65934581510006907000f, -0.13052619222005099000f, + 1.00000000000000000000f, 0.67155895484701833000f, -0.09801714032956068700f, + 1.00000000000000000000f, 0.68359230202287169000f, -0.06540312923014209000f, + 1.00000000000000000000f, 0.69544263500961112000f, -0.03271908282177764200f, + 1.00000000000000000000f, 0.70710678118654735000f, -0.00000000000000042861f, + 1.00000000000000000000f, 0.71858161777969765000f, 0.03271908282177501300f, + 1.00000000000000000000f, 0.72986407269783560000f, 0.06540312923014300600f, + 1.00000000000000000000f, 0.74095112535495888000f, 0.09801714032955984000f, + 1.00000000000000000000f, 0.75183980747897750000f, 0.13052619222005191000f, + 1.00000000000000000000f, 0.76252720390638740000f, 0.16289547339458660000f, + 1.00000000000000000000f, 0.77301045336273666000f, 0.19509032201612719000f, + 1.00000000000000000000f, 0.78328674922865038000f, 0.22707626303437317000f, + 1.00000000000000000000f, 0.79335334029123494000f, 0.25881904510252007000f, + 1.00000000000000000000f, 0.80320753148064505000f, 0.29028467725446266000f, + 1.00000000000000000000f, 0.81284668459161513000f, 0.32143946530316125000f, + 1.00000000000000000000f, 0.82226821898977531000f, 0.35225004792123416000f, + 1.00000000000000000000f, 0.83146961230254479000f, 0.38268343236508812000f, + 1.00000000000000000000f, 0.84044840109443786000f, 0.41270702980439411000f, + 1.00000000000000000000f, 0.84920218152657856000f, 0.44228869021900002000f, + 1.00000000000000000000f, 0.85772861000027201000f, 0.47139673682599736000f, + 1.00000000000000000000f, 0.86602540378443837000f, 0.49999999999999911000f, + 1.00000000000000000000f, 0.87409034162675880000f, 0.52806785065036799000f, + 1.00000000000000000000f, 0.88192126434835527000f, 0.55557023301960318000f, + 1.00000000000000000000f, 0.88951607542185573000f, 0.58247769686780104000f, + 1.00000000000000000000f, 0.89687274153268826000f, 0.60876142900872043000f, + 1.00000000000000000000f, 0.90398929312344312000f, 0.63439328416364471000f, + 1.00000000000000000000f, 0.91086382492117579000f, 0.65934581510006895000f, + 1.00000000000000000000f, 0.91749449644749115000f, 0.68359230202287080000f, + 1.00000000000000000000f, 0.92387953251128685000f, 0.70710678118654779000f, + 1.00000000000000000000f, 0.93001722368401174000f, 0.72986407269783427000f, + 1.00000000000000000000f, 0.93590592675732553000f, 0.75183980747897672000f, + 1.00000000000000000000f, 0.94154406518302081000f, 0.77301045336273699000f, + 1.00000000000000000000f, 0.94693012949510558000f, 0.79335334029123483000f, + 1.00000000000000000000f, 0.95206267771392428000f, 0.81284668459161546000f, + 1.00000000000000000000f, 0.95694033573220882000f, 0.83146961230254512000f, + 1.00000000000000000000f, 0.96156179768296202000f, 0.84920218152657934000f, + 1.00000000000000000000f, 0.96592582628906809000f, 0.86602540378443782000f, + 1.00000000000000000000f, 0.97003125319454397000f, 0.88192126434835472000f, + 1.00000000000000000000f, 0.97387697927733352000f, 0.89687274153268770000f, + 1.00000000000000000000f, 0.97746197494357179000f, 0.91086382492117568000f, + 1.00000000000000000000f, 0.98078528040323032000f, 0.92387953251128641000f, + 1.00000000000000000000f, 0.98384600592707738000f, 0.93590592675732576000f, + 1.00000000000000000000f, 0.98664333208487909000f, 0.94693012949510602000f, + 1.00000000000000000000f, 0.98917650996478090000f, 0.95694033573220849000f, + 1.00000000000000000000f, 0.99144486137381038000f, 0.96592582628906820000f, + 1.00000000000000000000f, 0.99344777901944437000f, 0.97387697927733341000f, + 1.00000000000000000000f, 0.99518472667219693000f, 0.98078528040323043000f, + 1.00000000000000000000f, 0.99665523930918032000f, 0.98664333208487887000f, + 1.00000000000000000000f, 0.99785892323860348000f, 0.99144486137381049000f, + 1.00000000000000000000f, 0.99879545620517229000f, 0.99518472667219671000f, + 1.00000000000000000000f, 0.99946458747636568000f, 0.99785892323860348000f, + 1.00000000000000000000f, 0.99986613790956180000f, 0.99946458747636557000f, + 1.00000000000000000000f, 1.00000000000000000000f, 1.00000000000000000000}; + +const FLOAT32 ia_rad_3_fft_twiddle_im[1155] = { + 0.00000000000000000000f, 0.00000000000000000000f, 0.00000000000000000000f, + 0.00000000000000000000f, -0.01636173162648678000f, -0.03271908282177613700f, + 0.00000000000000000000f, -0.03271908282177613700f, -0.06540312923014306200f, + 0.00000000000000000000f, -0.04906767432741801500f, -0.09801714032956060400f, + 0.00000000000000000000f, -0.06540312923014306200f, -0.13052619222005157000f, + 0.00000000000000000000f, -0.08172107413366822000f, -0.16289547339458874000f, + 0.00000000000000000000f, -0.09801714032956060400f, -0.19509032201612825000f, + 0.00000000000000000000f, -0.11428696496684639000f, -0.22707626303437320000f, + 0.00000000000000000000f, -0.13052619222005157000f, -0.25881904510252074000f, + 0.00000000000000000000f, -0.14673047445536175000f, -0.29028467725446233000f, + 0.00000000000000000000f, -0.16289547339458874000f, -0.32143946530316159000f, + 0.00000000000000000000f, -0.17901686127663266000f, -0.35225004792123349000f, + 0.00000000000000000000f, -0.19509032201612825000f, -0.38268343236508978000f, + 0.00000000000000000000f, -0.21111155235896517000f, -0.41270702980439472000f, + 0.00000000000000000000f, -0.22707626303437320000f, -0.44228869021900125000f, + 0.00000000000000000000f, -0.24298017990326384000f, -0.47139673682599759000f, + 0.00000000000000000000f, -0.25881904510252074000f, -0.49999999999999994000f, + 0.00000000000000000000f, -0.27458861818493235000f, -0.52806785065036799000f, + 0.00000000000000000000f, -0.29028467725446233000f, -0.55557023301960218000f, + 0.00000000000000000000f, -0.30590302009655346000f, -0.58247769686780215000f, + 0.00000000000000000000f, -0.32143946530316159000f, -0.60876142900872066000f, + 0.00000000000000000000f, -0.33688985339222005000f, -0.63439328416364549000f, + 0.00000000000000000000f, -0.35225004792123349000f, -0.65934581510006884000f, + 0.00000000000000000000f, -0.36751593659470350000f, -0.68359230202287125000f, + 0.00000000000000000000f, -0.38268343236508978000f, -0.70710678118654746000f, + 0.00000000000000000000f, -0.39774847452701106000f, -0.72986407269783571000f, + 0.00000000000000000000f, -0.41270702980439472000f, -0.75183980747897738000f, + 0.00000000000000000000f, -0.42755509343028208000f, -0.77301045336273699000f, + 0.00000000000000000000f, -0.44228869021900125000f, -0.79335334029123517000f, + 0.00000000000000000000f, -0.45690387563042067000f, -0.81284668459161524000f, + 0.00000000000000000000f, -0.47139673682599759000f, -0.83146961230254512000f, + 0.00000000000000000000f, -0.48576339371634003000f, -0.84920218152657889000f, + 0.00000000000000000000f, -0.49999999999999994000f, -0.86602540378443860000f, + 0.00000000000000000000f, -0.51410274419322177000f, -0.88192126434835505000f, + 0.00000000000000000000f, -0.52806785065036799000f, -0.89687274153268837000f, + 0.00000000000000000000f, -0.54189158057475173000f, -0.91086382492117579000f, + 0.00000000000000000000f, -0.55557023301960218000f, -0.92387953251128674000f, + 0.00000000000000000000f, -0.56910014587889823000f, -0.93590592675732565000f, + 0.00000000000000000000f, -0.58247769686780215000f, -0.94693012949510558000f, + 0.00000000000000000000f, -0.59569930449243325000f, -0.95694033573220882000f, + 0.00000000000000000000f, -0.60876142900872066000f, -0.96592582628906831000f, + 0.00000000000000000000f, -0.62166057337007730000f, -0.97387697927733363000f, + 0.00000000000000000000f, -0.63439328416364549000f, -0.98078528040323043000f, + 0.00000000000000000000f, -0.64695615253485728000f, -0.98664333208487898000f, + 0.00000000000000000000f, -0.65934581510006884000f, -0.99144486137381038000f, + 0.00000000000000000000f, -0.67155895484701844000f, -0.99518472667219693000f, + 0.00000000000000000000f, -0.68359230202287125000f, -0.99785892323860348000f, + 0.00000000000000000000f, -0.69544263500961168000f, -0.99946458747636568000f, + 0.00000000000000000000f, -0.70710678118654746000f, -1.00000000000000000000f, + 0.00000000000000000000f, -0.71858161777969798000f, -0.99946458747636568000f, + 0.00000000000000000000f, -0.72986407269783571000f, -0.99785892323860348000f, + 0.00000000000000000000f, -0.74095112535495899000f, -0.99518472667219693000f, + 0.00000000000000000000f, -0.75183980747897738000f, -0.99144486137381038000f, + 0.00000000000000000000f, -0.76252720390638806000f, -0.98664333208487898000f, + 0.00000000000000000000f, -0.77301045336273699000f, -0.98078528040323043000f, + 0.00000000000000000000f, -0.78328674922865038000f, -0.97387697927733363000f, + 0.00000000000000000000f, -0.79335334029123517000f, -0.96592582628906831000f, + 0.00000000000000000000f, -0.80320753148064483000f, -0.95694033573220894000f, + 0.00000000000000000000f, -0.81284668459161524000f, -0.94693012949510569000f, + 0.00000000000000000000f, -0.82226821898977509000f, -0.93590592675732576000f, + 0.00000000000000000000f, -0.83146961230254512000f, -0.92387953251128685000f, + 0.00000000000000000000f, -0.84044840109443797000f, -0.91086382492117590000f, + 0.00000000000000000000f, -0.84920218152657889000f, -0.89687274153268837000f, + 0.00000000000000000000f, -0.85772861000027212000f, -0.88192126434835505000f, + 0.00000000000000000000f, -0.86602540378443860000f, -0.86602540378443871000f, + 0.00000000000000000000f, -0.87409034162675880000f, -0.84920218152657889000f, + 0.00000000000000000000f, -0.88192126434835505000f, -0.83146961230254512000f, + 0.00000000000000000000f, -0.88951607542185596000f, -0.81284668459161524000f, + 0.00000000000000000000f, -0.89687274153268837000f, -0.79335334029123517000f, + 0.00000000000000000000f, -0.90398929312344334000f, -0.77301045336273710000f, + 0.00000000000000000000f, -0.91086382492117579000f, -0.75183980747897738000f, + 0.00000000000000000000f, -0.91749449644749137000f, -0.72986407269783560000f, + 0.00000000000000000000f, -0.92387953251128674000f, -0.70710678118654757000f, + 0.00000000000000000000f, -0.93001722368401207000f, -0.68359230202287158000f, + 0.00000000000000000000f, -0.93590592675732565000f, -0.65934581510006895000f, + 0.00000000000000000000f, -0.94154406518302081000f, -0.63439328416364549000f, + 0.00000000000000000000f, -0.94693012949510558000f, -0.60876142900872088000f, + 0.00000000000000000000f, -0.95206267771392428000f, -0.58247769686780215000f, + 0.00000000000000000000f, -0.95694033573220882000f, -0.55557023301960251000f, + 0.00000000000000000000f, -0.96156179768296191000f, -0.52806785065036810000f, + 0.00000000000000000000f, -0.96592582628906831000f, -0.49999999999999994000f, + 0.00000000000000000000f, -0.97003125319454397000f, -0.47139673682599786000f, + 0.00000000000000000000f, -0.97387697927733363000f, -0.44228869021900169000f, + 0.00000000000000000000f, -0.97746197494357190000f, -0.41270702980439461000f, + 0.00000000000000000000f, -0.98078528040323043000f, -0.38268343236508989000f, + 0.00000000000000000000f, -0.98384600592707738000f, -0.35225004792123343000f, + 0.00000000000000000000f, -0.98664333208487898000f, -0.32143946530316175000f, + 0.00000000000000000000f, -0.98917650996478090000f, -0.29028467725446278000f, + 0.00000000000000000000f, -0.99144486137381038000f, -0.25881904510252102000f, + 0.00000000000000000000f, -0.99344777901944437000f, -0.22707626303437328000f, + 0.00000000000000000000f, -0.99518472667219693000f, -0.19509032201612816000f, + 0.00000000000000000000f, -0.99665523930918032000f, -0.16289547339458890000f, + 0.00000000000000000000f, -0.99785892323860348000f, -0.13052619222005199000f, + 0.00000000000000000000f, -0.99879545620517241000f, -0.09801714032956082600f, + 0.00000000000000000000f, -0.99946458747636568000f, -0.06540312923014311700f, + 0.00000000000000000000f, -0.99986613790956180000f, -0.03271908282177600500f, + 0.00000000000000000000f, -1.00000000000000000000f, -0.00000000000000012246f, + 0.00000000000000000000f, -0.99986613790956180000f, 0.03271908282177576200f, + 0.00000000000000000000f, -0.99946458747636568000f, 0.06540312923014286700f, + 0.00000000000000000000f, -0.99879545620517241000f, 0.09801714032956059000f, + 0.00000000000000000000f, -0.99785892323860348000f, 0.13052619222005177000f, + 0.00000000000000000000f, -0.99665523930918032000f, 0.16289547339458865000f, + 0.00000000000000000000f, -0.99518472667219693000f, 0.19509032201612792000f, + 0.00000000000000000000f, -0.99344777901944437000f, 0.22707626303437303000f, + 0.00000000000000000000f, -0.99144486137381038000f, 0.25881904510252079000f, + 0.00000000000000000000f, -0.98917650996478090000f, 0.29028467725446255000f, + 0.00000000000000000000f, -0.98664333208487898000f, 0.32143946530316153000f, + 0.00000000000000000000f, -0.98384600592707749000f, 0.35225004792123321000f, + 0.00000000000000000000f, -0.98078528040323043000f, 0.38268343236508967000f, + 0.00000000000000000000f, -0.97746197494357190000f, 0.41270702980439439000f, + 0.00000000000000000000f, -0.97387697927733363000f, 0.44228869021900147000f, + 0.00000000000000000000f, -0.97003125319454397000f, 0.47139673682599764000f, + 0.00000000000000000000f, -0.96592582628906831000f, 0.49999999999999972000f, + 0.00000000000000000000f, -0.96156179768296202000f, 0.52806785065036788000f, + 0.00000000000000000000f, -0.95694033573220894000f, 0.55557023301960196000f, + 0.00000000000000000000f, -0.95206267771392417000f, 0.58247769686780237000f, + 0.00000000000000000000f, -0.94693012949510569000f, 0.60876142900872066000f, + 0.00000000000000000000f, -0.94154406518302081000f, 0.63439328416364527000f, + 0.00000000000000000000f, -0.93590592675732576000f, 0.65934581510006884000f, + 0.00000000000000000000f, -0.93001722368401218000f, 0.68359230202287102000f, + 0.00000000000000000000f, -0.92387953251128685000f, 0.70710678118654713000f, + 0.00000000000000000000f, -0.91749449644749126000f, 0.72986407269783571000f, + 0.00000000000000000000f, -0.91086382492117590000f, 0.75183980747897727000f, + 0.00000000000000000000f, -0.90398929312344345000f, 0.77301045336273666000f, + 0.00000000000000000000f, -0.89687274153268837000f, 0.79335334029123494000f, + 0.00000000000000000000f, -0.88951607542185607000f, 0.81284668459161513000f, + 0.00000000000000000000f, -0.88192126434835505000f, 0.83146961230254524000f, + 0.00000000000000000000f, -0.87409034162675880000f, 0.84920218152657900000f, + 0.00000000000000000000f, -0.86602540378443871000f, 0.86602540378443837000f, + 0.00000000000000000000f, -0.85772861000027212000f, 0.88192126434835494000f, + 0.00000000000000000000f, -0.84920218152657889000f, 0.89687274153268826000f, + 0.00000000000000000000f, -0.84044840109443797000f, 0.91086382492117590000f, + 0.00000000000000000000f, -0.83146961230254512000f, 0.92387953251128685000f, + 0.00000000000000000000f, -0.82226821898977520000f, 0.93590592675732553000f, + 0.00000000000000000000f, -0.81284668459161524000f, 0.94693012949510558000f, + 0.00000000000000000000f, -0.80320753148064494000f, 0.95694033573220882000f, + 0.00000000000000000000f, -0.79335334029123517000f, 0.96592582628906831000f, + 0.00000000000000000000f, -0.78328674922865027000f, 0.97387697927733374000f, + 0.00000000000000000000f, -0.77301045336273710000f, 0.98078528040323032000f, + 0.00000000000000000000f, -0.76252720390638817000f, 0.98664333208487898000f, + 0.00000000000000000000f, -0.75183980747897738000f, 0.99144486137381038000f, + 0.00000000000000000000f, -0.74095112535495933000f, 0.99518472667219682000f, + 0.00000000000000000000f, -0.72986407269783560000f, 0.99785892323860348000f, + 0.00000000000000000000f, -0.71858161777969820000f, 0.99946458747636568000f, + 0.00000000000000000000f, -0.70710678118654757000f, 1.00000000000000000000f, + 0.00000000000000000000f, -0.69544263500961168000f, 0.99946458747636568000f, + 0.00000000000000000000f, -0.68359230202287158000f, 0.99785892323860359000f, + 0.00000000000000000000f, -0.67155895484701822000f, 0.99518472667219682000f, + 0.00000000000000000000f, -0.65934581510006895000f, 0.99144486137381049000f, + 0.00000000000000000000f, -0.64695615253485739000f, 0.98664333208487898000f, + 0.00000000000000000000f, -0.63439328416364549000f, 0.98078528040323043000f, + 0.00000000000000000000f, -0.62166057337007763000f, 0.97387697927733385000f, + 0.00000000000000000000f, -0.60876142900872088000f, 0.96592582628906842000f, + 0.00000000000000000000f, -0.59569930449243347000f, 0.95694033573220894000f, + 0.00000000000000000000f, -0.58247769686780215000f, 0.94693012949510569000f, + 0.00000000000000000000f, -0.56910014587889823000f, 0.93590592675732565000f, + 0.00000000000000000000f, -0.55557023301960251000f, 0.92387953251128696000f, + 0.00000000000000000000f, -0.54189158057475195000f, 0.91086382492117601000f, + 0.00000000000000000000f, -0.52806785065036810000f, 0.89687274153268848000f, + 0.00000000000000000000f, -0.51410274419322177000f, 0.88192126434835505000f, + 0.00000000000000000000f, -0.49999999999999994000f, 0.86602540378443860000f, + 0.00000000000000000000f, -0.48576339371634031000f, 0.84920218152657923000f, + 0.00000000000000000000f, -0.47139673682599786000f, 0.83146961230254546000f, + 0.00000000000000000000f, -0.45690387563042079000f, 0.81284668459161535000f, + 0.00000000000000000000f, -0.44228869021900169000f, 0.79335334029123572000f, + 0.00000000000000000000f, -0.42755509343028242000f, 0.77301045336273744000f, + 0.00000000000000000000f, -0.41270702980439461000f, 0.75183980747897716000f, + 0.00000000000000000000f, -0.39774847452701084000f, 0.72986407269783538000f, + 0.00000000000000000000f, -0.38268343236508989000f, 0.70710678118654768000f, + 0.00000000000000000000f, -0.36751593659470361000f, 0.68359230202287136000f, + 0.00000000000000000000f, -0.35225004792123343000f, 0.65934581510006873000f, + 0.00000000000000000000f, -0.33688985339222033000f, 0.63439328416364593000f, + 0.00000000000000000000f, -0.32143946530316175000f, 0.60876142900872088000f, + 0.00000000000000000000f, -0.30590302009655357000f, 0.58247769686780226000f, + 0.00000000000000000000f, -0.29028467725446278000f, 0.55557023301960295000f, + 0.00000000000000000000f, -0.27458861818493269000f, 0.52806785065036854000f, + 0.00000000000000000000f, -0.25881904510252102000f, 0.50000000000000044000f, + 0.00000000000000000000f, -0.24298017990326362000f, 0.47139673682599714000f, + 0.00000000000000000000f, -0.22707626303437328000f, 0.44228869021900141000f, + 0.00000000000000000000f, -0.21111155235896514000f, 0.41270702980439472000f, + 0.00000000000000000000f, -0.19509032201612816000f, 0.38268343236508956000f, + 0.00000000000000000000f, -0.17901686127663291000f, 0.35225004792123399000f, + 0.00000000000000000000f, -0.16289547339458890000f, 0.32143946530316186000f, + 0.00000000000000000000f, -0.14673047445536180000f, 0.29028467725446250000f, + 0.00000000000000000000f, -0.13052619222005199000f, 0.25881904510252157000f, + 0.00000000000000000000f, -0.11428696496684672000f, 0.22707626303437384000f, + 0.00000000000000000000f, -0.09801714032956082600f, 0.19509032201612872000f, + 0.00000000000000000000f, -0.08172107413366791500f, 0.16289547339458813000f, + 0.00000000000000000000f, -0.06540312923014311700f, 0.13052619222005168000f, + 0.00000000000000000000f, -0.04906767432741796600f, 0.09801714032956050600f, + 0.00000000000000000000f, -0.03271908282177600500f, 0.06540312923014279800f, + 0.00000000000000000000f, -0.01636173162648699500f, 0.03271908282177657400f, + 0.00000000000000000000f, -0.00000000000000012246f, 0.00000000000000024492f, + 0.00000000000000000000f, 0.01636173162648675200f, -0.03271908282177608100f, + 0.00000000000000000000f, 0.03271908282177576200f, -0.06540312923014229800f, + 0.00000000000000000000f, 0.04906767432741772400f, -0.09801714032956002100f, + 0.00000000000000000000f, 0.06540312923014286700f, -0.13052619222005118000f, + 0.00000000000000000000f, 0.08172107413366767900f, -0.16289547339458765000f, + 0.00000000000000000000f, 0.09801714032956059000f, -0.19509032201612825000f, + 0.00000000000000000000f, 0.11428696496684647000f, -0.22707626303437337000f, + 0.00000000000000000000f, 0.13052619222005177000f, -0.25881904510252107000f, + 0.00000000000000000000f, 0.14673047445536158000f, -0.29028467725446200000f, + 0.00000000000000000000f, 0.16289547339458865000f, -0.32143946530316142000f, + 0.00000000000000000000f, 0.17901686127663269000f, -0.35225004792123349000f, + 0.00000000000000000000f, 0.19509032201612792000f, -0.38268343236508912000f, + 0.00000000000000000000f, 0.21111155235896492000f, -0.41270702980439428000f, + 0.00000000000000000000f, 0.22707626303437303000f, -0.44228869021900097000f, + 0.00000000000000000000f, 0.24298017990326337000f, -0.47139673682599675000f, + 0.00000000000000000000f, 0.25881904510252079000f, -0.50000000000000000000f, + 0.00000000000000000000f, 0.27458861818493246000f, -0.52806785065036821000f, + 0.00000000000000000000f, 0.29028467725446255000f, -0.55557023301960251000f, + 0.00000000000000000000f, 0.30590302009655329000f, -0.58247769686780193000f, + 0.00000000000000000000f, 0.32143946530316153000f, -0.60876142900872054000f, + 0.00000000000000000000f, 0.33688985339222011000f, -0.63439328416364560000f, + 0.00000000000000000000f, 0.35225004792123321000f, -0.65934581510006840000f, + 0.00000000000000000000f, 0.36751593659470333000f, -0.68359230202287091000f, + 0.00000000000000000000f, 0.38268343236508967000f, -0.70710678118654735000f, + 0.00000000000000000000f, 0.39774847452701062000f, -0.72986407269783504000f, + 0.00000000000000000000f, 0.41270702980439439000f, -0.75183980747897683000f, + 0.00000000000000000000f, 0.42755509343028220000f, -0.77301045336273710000f, + 0.00000000000000000000f, 0.44228869021900147000f, -0.79335334029123550000f, + 0.00000000000000000000f, 0.45690387563042056000f, -0.81284668459161502000f, + 0.00000000000000000000f, 0.47139673682599764000f, -0.83146961230254524000f, + 0.00000000000000000000f, 0.48576339371634009000f, -0.84920218152657900000f, + 0.00000000000000000000f, 0.49999999999999972000f, -0.86602540378443837000f, + 0.00000000000000000000f, 0.51410274419322155000f, -0.88192126434835483000f, + 0.00000000000000000000f, 0.52806785065036788000f, -0.89687274153268826000f, + 0.00000000000000000000f, 0.54189158057475129000f, -0.91086382492117546000f, + 0.00000000000000000000f, 0.55557023301960196000f, -0.92387953251128652000f, + 0.00000000000000000000f, 0.56910014587889801000f, -0.93590592675732553000f, + 0.00000000000000000000f, 0.58247769686780237000f, -0.94693012949510580000f, + 0.00000000000000000000f, 0.59569930449243325000f, -0.95694033573220882000f, + 0.00000000000000000000f, 0.60876142900872066000f, -0.96592582628906831000f, + 0.00000000000000000000f, 0.62166057337007752000f, -0.97387697927733374000f, + 0.00000000000000000000f, 0.63439328416364527000f, -0.98078528040323032000f, + 0.00000000000000000000f, 0.64695615253485728000f, -0.98664333208487898000f, + 0.00000000000000000000f, 0.65934581510006884000f, -0.99144486137381038000f, + 0.00000000000000000000f, 0.67155895484701811000f, -0.99518472667219682000f, + 0.00000000000000000000f, 0.68359230202287102000f, -0.99785892323860348000f, + 0.00000000000000000000f, 0.69544263500961145000f, -0.99946458747636557000f, + 0.00000000000000000000f, 0.70710678118654713000f, -1.00000000000000000000f, + 0.00000000000000000000f, 0.71858161777969798000f, -0.99946458747636568000f, + 0.00000000000000000000f, 0.72986407269783571000f, -0.99785892323860348000f, + 0.00000000000000000000f, 0.74095112535495922000f, -0.99518472667219682000f, + 0.00000000000000000000f, 0.75183980747897727000f, -0.99144486137381049000f, + 0.00000000000000000000f, 0.76252720390638806000f, -0.98664333208487909000f, + 0.00000000000000000000f, 0.77301045336273666000f, -0.98078528040323065000f, + 0.00000000000000000000f, 0.78328674922865038000f, -0.97387697927733363000f, + 0.00000000000000000000f, 0.79335334029123494000f, -0.96592582628906842000f, + 0.00000000000000000000f, 0.80320753148064450000f, -0.95694033573220927000f, + 0.00000000000000000000f, 0.81284668459161513000f, -0.94693012949510569000f, + 0.00000000000000000000f, 0.82226821898977531000f, -0.93590592675732542000f, + 0.00000000000000000000f, 0.83146961230254524000f, -0.92387953251128674000f, + 0.00000000000000000000f, 0.84044840109443786000f, -0.91086382492117601000f, + 0.00000000000000000000f, 0.84920218152657900000f, -0.89687274153268803000f, + 0.00000000000000000000f, 0.85772861000027201000f, -0.88192126434835516000f, + 0.00000000000000000000f, 0.86602540378443837000f, -0.86602540378443915000f, + 0.00000000000000000000f, 0.87409034162675892000f, -0.84920218152657878000f, + 0.00000000000000000000f, 0.88192126434835494000f, -0.83146961230254557000f, + 0.00000000000000000000f, 0.88951607542185573000f, -0.81284668459161591000f, + 0.00000000000000000000f, 0.89687274153268826000f, -0.79335334029123528000f, + 0.00000000000000000000f, 0.90398929312344312000f, -0.77301045336273755000f, + 0.00000000000000000000f, 0.91086382492117590000f, -0.75183980747897727000f, + 0.00000000000000000000f, 0.91749449644749126000f, -0.72986407269783604000f, + 0.00000000000000000000f, 0.92387953251128685000f, -0.70710678118654713000f, + 0.00000000000000000000f, 0.93001722368401207000f, -0.68359230202287136000f, + 0.00000000000000000000f, 0.93590592675732553000f, -0.65934581510006951000f, + 0.00000000000000000000f, 0.94154406518302081000f, -0.63439328416364538000f, + 0.00000000000000000000f, 0.94693012949510558000f, -0.60876142900872099000f, + 0.00000000000000000000f, 0.95206267771392405000f, -0.58247769686780315000f, + 0.00000000000000000000f, 0.95694033573220882000f, -0.55557023301960229000f, + 0.00000000000000000000f, 0.96156179768296179000f, -0.52806785065036865000f, + 0.00000000000000000000f, 0.96592582628906831000f, -0.49999999999999978000f, + 0.00000000000000000000f, 0.97003125319454397000f, -0.47139673682599803000f, + 0.00000000000000000000f, 0.97387697927733374000f, -0.44228869021900075000f, + 0.00000000000000000000f, 0.97746197494357190000f, -0.41270702980439483000f, + 0.00000000000000000000f, 0.98078528040323032000f, -0.38268343236509050000f, + 0.00000000000000000000f, 0.98384600592707749000f, -0.35225004792123327000f, + 0.00000000000000000000f, 0.98664333208487898000f, -0.32143946530316198000f, + 0.00000000000000000000f, 0.98917650996478090000f, -0.29028467725446344000f, + 0.00000000000000000000f, 0.99144486137381038000f, -0.25881904510252079000f, + 0.00000000000000000000f, 0.99344777901944437000f, -0.22707626303437395000f, + 0.00000000000000000000f, 0.99518472667219682000f, -0.19509032201612972000f, + 0.00000000000000000000f, 0.99665523930918032000f, -0.16289547339458912000f, + 0.00000000000000000000f, 0.99785892323860348000f, -0.13052619222005094000f, + 0.00000000000000000000f, 0.99879545620517241000f, -0.09801714032956063100f, + 0.00000000000000000000f, 0.99946458747636568000f, -0.06540312923014379700f, + 0.00000000000000000000f, 0.99986613790956180000f, -0.03271908282177580400f, + 0.00000000000000000000f, 1.00000000000000000000f, -0.00000000000000036738f, + 0.00000000000000000000f, 0.99986613790956180000f, 0.03271908282177506800f, + 0.00000000000000000000f, 0.99946458747636568000f, 0.06540312923014306200f, + 0.00000000000000000000f, 0.99879545620517241000f, 0.09801714032955989600f, + 0.00000000000000000000f, 0.99785892323860359000f, 0.13052619222005019000f, + 0.00000000000000000000f, 0.99665523930918032000f, 0.16289547339458840000f, + 0.00000000000000000000f, 0.99518472667219682000f, 0.19509032201612900000f, + 0.00000000000000000000f, 0.99344777901944437000f, 0.22707626303437323000f, + 0.00000000000000000000f, 0.99144486137381049000f, 0.25881904510252013000f, + 0.00000000000000000000f, 0.98917650996478090000f, 0.29028467725446278000f, + 0.00000000000000000000f, 0.98664333208487898000f, 0.32143946530316131000f, + 0.00000000000000000000f, 0.98384600592707749000f, 0.35225004792123255000f, + 0.00000000000000000000f, 0.98078528040323043000f, 0.38268343236508984000f, + 0.00000000000000000000f, 0.97746197494357190000f, 0.41270702980439417000f, + 0.00000000000000000000f, 0.97387697927733385000f, 0.44228869021900008000f, + 0.00000000000000000000f, 0.97003125319454397000f, 0.47139673682599742000f, + 0.00000000000000000000f, 0.96592582628906842000f, 0.49999999999999917000f, + 0.00000000000000000000f, 0.96156179768296191000f, 0.52806785065036810000f, + 0.00000000000000000000f, 0.95694033573220894000f, 0.55557023301960173000f, + 0.00000000000000000000f, 0.95206267771392417000f, 0.58247769686780249000f, + 0.00000000000000000000f, 0.94693012949510569000f, 0.60876142900872043000f, + 0.00000000000000000000f, 0.94154406518302092000f, 0.63439328416364471000f, + 0.00000000000000000000f, 0.93590592675732565000f, 0.65934581510006895000f, + 0.00000000000000000000f, 0.93001722368401218000f, 0.68359230202287080000f, + 0.00000000000000000000f, 0.92387953251128696000f, 0.70710678118654657000f, + 0.00000000000000000000f, 0.91749449644749137000f, 0.72986407269783549000f, + 0.00000000000000000000f, 0.91086382492117601000f, 0.75183980747897683000f, + 0.00000000000000000000f, 0.90398929312344334000f, 0.77301045336273710000f, + 0.00000000000000000000f, 0.89687274153268848000f, 0.79335334029123483000f, + 0.00000000000000000000f, 0.88951607542185596000f, 0.81284668459161546000f, + 0.00000000000000000000f, 0.88192126434835505000f, 0.83146961230254512000f, + 0.00000000000000000000f, 0.87409034162675903000f, 0.84920218152657845000f, + 0.00000000000000000000f, 0.86602540378443860000f, 0.86602540378443871000f, + 0.00000000000000000000f, 0.85772861000027223000f, 0.88192126434835483000f, + 0.00000000000000000000f, 0.84920218152657923000f, 0.89687274153268781000f, + 0.00000000000000000000f, 0.84044840109443808000f, 0.91086382492117579000f, + 0.00000000000000000000f, 0.83146961230254546000f, 0.92387953251128641000f, + 0.00000000000000000000f, 0.82226821898977553000f, 0.93590592675732520000f, + 0.00000000000000000000f, 0.81284668459161535000f, 0.94693012949510547000f, + 0.00000000000000000000f, 0.80320753148064472000f, 0.95694033573220905000f, + 0.00000000000000000000f, 0.79335334029123572000f, 0.96592582628906776000f, + 0.00000000000000000000f, 0.78328674922865060000f, 0.97387697927733341000f, + 0.00000000000000000000f, 0.77301045336273744000f, 0.98078528040323010000f, + 0.00000000000000000000f, 0.76252720390638828000f, 0.98664333208487898000f, + 0.00000000000000000000f, 0.75183980747897716000f, 0.99144486137381049000f, + 0.00000000000000000000f, 0.74095112535495911000f, 0.99518472667219693000f, + 0.00000000000000000000f, 0.72986407269783538000f, 0.99785892323860359000f, + 0.00000000000000000000f, 0.71858161777969853000f, 0.99946458747636557000f, + 0.00000000000000000000f, 0.70710678118654768000f, 1.00000000000000000000f, + 0.00000000000000000000f, 0.69544263500961201000f, 0.99946458747636568000f, + 0.00000000000000000000f, 0.68359230202287136000f, 0.99785892323860348000f, + 0.00000000000000000000f, 0.67155895484701866000f, 0.99518472667219693000f, + 0.00000000000000000000f, 0.65934581510006873000f, 0.99144486137381038000f, + 0.00000000000000000000f, 0.64695615253485816000f, 0.98664333208487931000f, + 0.00000000000000000000f, 0.63439328416364593000f, 0.98078528040323065000f, + 0.00000000000000000000f, 0.62166057337007741000f, 0.97387697927733363000f, + 0.00000000000000000000f, 0.60876142900872088000f, 0.96592582628906842000f, + 0.00000000000000000000f, 0.59569930449243325000f, 0.95694033573220871000f, + 0.00000000000000000000f, 0.58247769686780226000f, 0.94693012949510580000f, + 0.00000000000000000000f, 0.56910014587889790000f, 0.93590592675732542000f, + 0.00000000000000000000f, 0.55557023301960295000f, 0.92387953251128740000f, + 0.00000000000000000000f, 0.54189158057475206000f, 0.91086382492117612000f, + 0.00000000000000000000f, 0.52806785065036854000f, 0.89687274153268892000f, + 0.00000000000000000000f, 0.51410274419322188000f, 0.88192126434835516000f, + 0.00000000000000000000f, 0.50000000000000044000f, 0.86602540378443915000f, + 0.00000000000000000000f, 0.48576339371634003000f, 0.84920218152657889000f, + 0.00000000000000000000f, 0.47139673682599714000f, 0.83146961230254457000f, + 0.00000000000000000000f, 0.45690387563042129000f, 0.81284668459161602000f, + 0.00000000000000000000f, 0.44228869021900141000f, 0.79335334029123539000f, + 0.00000000000000000000f, 0.42755509343028253000f, 0.77301045336273755000f, + 0.00000000000000000000f, 0.41270702980439472000f, 0.75183980747897738000f, + 0.00000000000000000000f, 0.39774847452701134000f, 0.72986407269783604000f, + 0.00000000000000000000f, 0.38268343236508956000f, 0.70710678118654724000f, + 0.00000000000000000000f, 0.36751593659470450000f, 0.68359230202287280000f, + 0.00000000000000000000f, 0.35225004792123399000f, 0.65934581510006962000f, + 0.00000000000000000000f, 0.33688985339222000000f, 0.63439328416364538000f, + 0.00000000000000000000f, 0.32143946530316186000f, 0.60876142900872110000f, + 0.00000000000000000000f, 0.30590302009655324000f, 0.58247769686780182000f, + 0.00000000000000000000f, 0.29028467725446250000f, 0.55557023301960240000f, + 0.00000000000000000000f, 0.27458861818493197000f, 0.52806785065036732000f, + 0.00000000000000000000f, 0.25881904510252157000f, 0.50000000000000144000f, + 0.00000000000000000000f, 0.24298017990326418000f, 0.47139673682599814000f, + 0.00000000000000000000f, 0.22707626303437384000f, 0.44228869021900241000f, + 0.00000000000000000000f, 0.21111155235896528000f, 0.41270702980439494000f, + 0.00000000000000000000f, 0.19509032201612872000f, 0.38268343236509061000f, + 0.00000000000000000000f, 0.17901686127663261000f, 0.35225004792123338000f, + 0.00000000000000000000f, 0.16289547339458813000f, 0.32143946530316042000f, + 0.00000000000000000000f, 0.14673047445536239000f, 0.29028467725446355000f, + 0.00000000000000000000f, 0.13052619222005168000f, 0.25881904510252096000f, + 0.00000000000000000000f, 0.11428696496684684000f, 0.22707626303437406000f, + 0.00000000000000000000f, 0.09801714032956050600f, 0.19509032201612808000f, + 0.00000000000000000000f, 0.08172107413366848400f, 0.16289547339458926000f, + 0.00000000000000000000f, 0.06540312923014279800f, 0.13052619222005105000f, + 0.00000000000000000000f, 0.04906767432741897900f, 0.09801714032956251900f, + 0.00000000000000000000f, 0.03271908282177657400f, 0.06540312923014392200f, + 0.00000000000000000000f, 0.01636173162648756400f, 0.03271908282177770500f, + 0.00000000000000000000f, 0.00000000000000024492f, 0.00000000000000048984f}; + +const FLOAT32 ia_fft_mix_rad_twid_tbl_336[564] = { + -0.018699f, 0.999825f, -0.037391f, 0.999301f, -0.056070f, 0.998427f, -0.074730f, + 0.997204f, -0.093364f, 0.995632f, -0.111964f, 0.993712f, -0.130526f, 0.991445f, + -0.149042f, 0.988831f, -0.167506f, 0.985871f, -0.185912f, 0.982566f, -0.204252f, + 0.978918f, -0.222521f, 0.974928f, -0.240712f, 0.970597f, -0.258819f, 0.965926f, + -0.276836f, 0.960917f, -0.294755f, 0.955573f, -0.312572f, 0.949894f, -0.330279f, + 0.943883f, -0.347871f, 0.937542f, -0.365341f, 0.930874f, -0.382683f, 0.923880f, + -0.399892f, 0.916562f, -0.416961f, 0.908924f, -0.433884f, 0.900969f, -0.450655f, + 0.892698f, -0.467269f, 0.884115f, -0.483719f, 0.875223f, -0.500000f, 0.866025f, + -0.516106f, 0.856525f, -0.532032f, 0.846724f, -0.547772f, 0.836628f, -0.563320f, + 0.826239f, -0.578671f, 0.815561f, -0.593820f, 0.804598f, -0.608761f, 0.793353f, + -0.623490f, 0.781832f, -0.638000f, 0.770036f, -0.652287f, 0.757972f, -0.666347f, + 0.745642f, -0.680173f, 0.733052f, -0.693761f, 0.720205f, -0.707107f, 0.707107f, + -0.720205f, 0.693761f, -0.733052f, 0.680173f, -0.745642f, 0.666347f, -0.757972f, + 0.652287f, -0.770036f, 0.638000f, -0.037391f, 0.999301f, -0.074730f, 0.997204f, + -0.111964f, 0.993712f, -0.149042f, 0.988831f, -0.185912f, 0.982566f, -0.222521f, + 0.974928f, -0.258819f, 0.965926f, -0.294755f, 0.955573f, -0.330279f, 0.943883f, + -0.365341f, 0.930874f, -0.399892f, 0.916562f, -0.433884f, 0.900969f, -0.467269f, + 0.884115f, -0.500000f, 0.866025f, -0.532032f, 0.846724f, -0.563320f, 0.826239f, + -0.593820f, 0.804598f, -0.623490f, 0.781832f, -0.652287f, 0.757972f, -0.680173f, + 0.733052f, -0.707107f, 0.707107f, -0.733052f, 0.680173f, -0.757972f, 0.652287f, + -0.781832f, 0.623490f, -0.804598f, 0.593820f, -0.826239f, 0.563320f, -0.846724f, + 0.532032f, -0.866025f, 0.500000f, -0.884115f, 0.467269f, -0.900969f, 0.433884f, + -0.916562f, 0.399892f, -0.930874f, 0.365341f, -0.943883f, 0.330279f, -0.955573f, + 0.294755f, -0.965926f, 0.258819f, -0.974928f, 0.222521f, -0.982566f, 0.185912f, + -0.988831f, 0.149042f, -0.993712f, 0.111964f, -0.997204f, 0.074730f, -0.999301f, + 0.037391f, -1.000000f, 0.000000f, -0.999301f, -0.037391f, -0.997204f, -0.074730f, + -0.993712f, -0.111964f, -0.988831f, -0.149042f, -0.982566f, -0.185912f, -0.056070f, + 0.998427f, -0.111964f, 0.993712f, -0.167506f, 0.985871f, -0.222521f, 0.974928f, + -0.276836f, 0.960917f, -0.330279f, 0.943883f, -0.382683f, 0.923880f, -0.433884f, + 0.900969f, -0.483719f, 0.875223f, -0.532032f, 0.846724f, -0.578671f, 0.815561f, + -0.623490f, 0.781832f, -0.666347f, 0.745642f, -0.707107f, 0.707107f, -0.745642f, + 0.666347f, -0.781832f, 0.623490f, -0.815561f, 0.578671f, -0.846724f, 0.532032f, + -0.875223f, 0.483719f, -0.900969f, 0.433884f, -0.923880f, 0.382683f, -0.943883f, + 0.330279f, -0.960917f, 0.276836f, -0.974928f, 0.222521f, -0.985871f, 0.167506f, + -0.993712f, 0.111964f, -0.998427f, 0.056070f, -1.000000f, 0.000000f, -0.998427f, + -0.056070f, -0.993712f, -0.111964f, -0.985871f, -0.167506f, -0.974928f, -0.222521f, + -0.960917f, -0.276836f, -0.943883f, -0.330279f, -0.923880f, -0.382683f, -0.900969f, + -0.433884f, -0.875223f, -0.483719f, -0.846724f, -0.532032f, -0.815561f, -0.578671f, + -0.781832f, -0.623490f, -0.745642f, -0.666347f, -0.707107f, -0.707107f, -0.666347f, + -0.745642f, -0.623490f, -0.781832f, -0.578671f, -0.815561f, -0.532032f, -0.846724f, + -0.483719f, -0.875223f, -0.074730f, 0.997204f, -0.149042f, 0.988831f, -0.222521f, + 0.974928f, -0.294755f, 0.955573f, -0.365341f, 0.930874f, -0.433884f, 0.900969f, + -0.500000f, 0.866025f, -0.563320f, 0.826239f, -0.623490f, 0.781832f, -0.680173f, + 0.733052f, -0.733052f, 0.680173f, -0.781832f, 0.623490f, -0.826239f, 0.563320f, + -0.866025f, 0.500000f, -0.900969f, 0.433884f, -0.930874f, 0.365341f, -0.955573f, + 0.294755f, -0.974928f, 0.222521f, -0.988831f, 0.149042f, -0.997204f, 0.074730f, + -1.000000f, 0.000000f, -0.997204f, -0.074730f, -0.988831f, -0.149042f, -0.974928f, + -0.222521f, -0.955573f, -0.294755f, -0.930874f, -0.365341f, -0.900969f, -0.433884f, + -0.866025f, -0.500000f, -0.826239f, -0.563320f, -0.781832f, -0.623490f, -0.733052f, + -0.680173f, -0.680173f, -0.733052f, -0.623490f, -0.781832f, -0.563320f, -0.826239f, + -0.500000f, -0.866025f, -0.433884f, -0.900969f, -0.365341f, -0.930874f, -0.294755f, + -0.955573f, -0.222521f, -0.974928f, -0.149042f, -0.988831f, -0.074730f, -0.997204f, + -0.000000f, -1.000000f, 0.074730f, -0.997204f, 0.149042f, -0.988831f, 0.222521f, + -0.974928f, 0.294755f, -0.955573f, 0.365341f, -0.930874f, -0.093364f, 0.995632f, + -0.185912f, 0.982566f, -0.276836f, 0.960917f, -0.365341f, 0.930874f, -0.450655f, + 0.892698f, -0.532032f, 0.846724f, -0.608761f, 0.793353f, -0.680173f, 0.733052f, + -0.745642f, 0.666347f, -0.804598f, 0.593820f, -0.856525f, 0.516106f, -0.900969f, + 0.433884f, -0.937542f, 0.347871f, -0.965926f, 0.258819f, -0.985871f, 0.167506f, + -0.997204f, 0.074730f, -0.999825f, -0.018699f, -0.993712f, -0.111964f, -0.978918f, + -0.204252f, -0.955573f, -0.294755f, -0.923880f, -0.382683f, -0.884115f, -0.467269f, + -0.836628f, -0.547772f, -0.781832f, -0.623490f, -0.720205f, -0.693761f, -0.652287f, + -0.757972f, -0.578671f, -0.815561f, -0.500000f, -0.866025f, -0.416961f, -0.908924f, + -0.330279f, -0.943883f, -0.240712f, -0.970597f, -0.149042f, -0.988831f, -0.056070f, + -0.998427f, 0.037391f, -0.999301f, 0.130526f, -0.991445f, 0.222521f, -0.974928f, + 0.312572f, -0.949894f, 0.399892f, -0.916562f, 0.483719f, -0.875223f, 0.563320f, + -0.826239f, 0.638000f, -0.770036f, 0.707107f, -0.707107f, 0.770036f, -0.638000f, + 0.826239f, -0.563320f, 0.875223f, -0.483719f, 0.916562f, -0.399892f, 0.949894f, + -0.312572f, -0.111964f, 0.993712f, -0.222521f, 0.974928f, -0.330279f, 0.943883f, + -0.433884f, 0.900969f, -0.532032f, 0.846724f, -0.623490f, 0.781832f, -0.707107f, + 0.707107f, -0.781832f, 0.623490f, -0.846724f, 0.532032f, -0.900969f, 0.433884f, + -0.943883f, 0.330279f, -0.974928f, 0.222521f, -0.993712f, 0.111964f, -1.000000f, + 0.000000f, -0.993712f, -0.111964f, -0.974928f, -0.222521f, -0.943883f, -0.330279f, + -0.900969f, -0.433884f, -0.846724f, -0.532032f, -0.781832f, -0.623490f, -0.707107f, + -0.707107f, -0.623490f, -0.781832f, -0.532032f, -0.846724f, -0.433884f, -0.900969f, + -0.330279f, -0.943883f, -0.222521f, -0.974928f, -0.111964f, -0.993712f, -0.000000f, + -1.000000f, 0.111964f, -0.993712f, 0.222521f, -0.974928f, 0.330279f, -0.943883f, + 0.433884f, -0.900969f, 0.532032f, -0.846724f, 0.623490f, -0.781832f, 0.707107f, + -0.707107f, 0.781832f, -0.623490f, 0.846724f, -0.532032f, 0.900969f, -0.433884f, + 0.943883f, -0.330279f, 0.974928f, -0.222521f, 0.993712f, -0.111964f, 1.000000f, + -0.000000f, 0.993712f, 0.111964f, 0.974928f, 0.222521f, 0.943883f, 0.330279f, + 0.900969f, 0.433884f, 0.846724f, 0.532032f}; + +const FLOAT32 ia_fft_mix_rad_twid_tbl_168[276] = { + -0.037391f, 0.999301f, -0.074730f, 0.997204f, -0.111964f, 0.993712f, -0.149042f, + 0.988831f, -0.185912f, 0.982566f, -0.222521f, 0.974928f, -0.258819f, 0.965926f, + -0.294755f, 0.955573f, -0.330279f, 0.943883f, -0.365341f, 0.930874f, -0.399892f, + 0.916562f, -0.433884f, 0.900969f, -0.467269f, 0.884115f, -0.500000f, 0.866025f, + -0.532032f, 0.846724f, -0.563320f, 0.826239f, -0.593820f, 0.804598f, -0.623490f, + 0.781832f, -0.652287f, 0.757972f, -0.680173f, 0.733052f, -0.707107f, 0.707107f, + -0.733052f, 0.680173f, -0.757972f, 0.652287f, -0.074730f, 0.997204f, -0.149042f, + 0.988831f, -0.222521f, 0.974928f, -0.294755f, 0.955573f, -0.365341f, 0.930874f, + -0.433884f, 0.900969f, -0.500000f, 0.866025f, -0.563320f, 0.826239f, -0.623490f, + 0.781832f, -0.680173f, 0.733052f, -0.733052f, 0.680173f, -0.781832f, 0.623490f, + -0.826239f, 0.563320f, -0.866025f, 0.500000f, -0.900969f, 0.433884f, -0.930874f, + 0.365341f, -0.955573f, 0.294755f, -0.974928f, 0.222521f, -0.988831f, 0.149042f, + -0.997204f, 0.074730f, -1.000000f, 0.000000f, -0.997204f, -0.074730f, -0.988831f, + -0.149042f, -0.111964f, 0.993712f, -0.222521f, 0.974928f, -0.330279f, 0.943883f, + -0.433884f, 0.900969f, -0.532032f, 0.846724f, -0.623490f, 0.781832f, -0.707107f, + 0.707107f, -0.781832f, 0.623490f, -0.846724f, 0.532032f, -0.900969f, 0.433884f, + -0.943883f, 0.330279f, -0.974928f, 0.222521f, -0.993712f, 0.111964f, -1.000000f, + 0.000000f, -0.993712f, -0.111964f, -0.974928f, -0.222521f, -0.943883f, -0.330279f, + -0.900969f, -0.433884f, -0.846724f, -0.532032f, -0.781832f, -0.623490f, -0.707107f, + -0.707107f, -0.623490f, -0.781832f, -0.532032f, -0.846724f, -0.149042f, 0.988831f, + -0.294755f, 0.955573f, -0.433884f, 0.900969f, -0.563320f, 0.826239f, -0.680173f, + 0.733052f, -0.781832f, 0.623490f, -0.866025f, 0.500000f, -0.930874f, 0.365341f, + -0.974928f, 0.222521f, -0.997204f, 0.074730f, -0.997204f, -0.074730f, -0.974928f, + -0.222521f, -0.930874f, -0.365341f, -0.866025f, -0.500000f, -0.781832f, -0.623490f, + -0.680173f, -0.733052f, -0.563320f, -0.826239f, -0.433884f, -0.900969f, -0.294755f, + -0.955573f, -0.149042f, -0.988831f, -0.000000f, -1.000000f, 0.149042f, -0.988831f, + 0.294755f, -0.955573f, -0.185912f, 0.982566f, -0.365341f, 0.930874f, -0.532032f, + 0.846724f, -0.680173f, 0.733052f, -0.804598f, 0.593820f, -0.900969f, 0.433884f, + -0.965926f, 0.258819f, -0.997204f, 0.074730f, -0.993712f, -0.111964f, -0.955573f, + -0.294755f, -0.884115f, -0.467269f, -0.781832f, -0.623490f, -0.652287f, -0.757972f, + -0.500000f, -0.866025f, -0.330279f, -0.943883f, -0.149042f, -0.988831f, 0.037391f, + -0.999301f, 0.222521f, -0.974928f, 0.399892f, -0.916562f, 0.563320f, -0.826239f, + 0.707107f, -0.707107f, 0.826239f, -0.563320f, 0.916562f, -0.399892f, -0.222521f, + 0.974928f, -0.433884f, 0.900969f, -0.623490f, 0.781832f, -0.781832f, 0.623490f, + -0.900969f, 0.433884f, -0.974928f, 0.222521f, -1.000000f, 0.000000f, -0.974928f, + -0.222521f, -0.900969f, -0.433884f, -0.781832f, -0.623490f, -0.623490f, -0.781832f, + -0.433884f, -0.900969f, -0.222521f, -0.974928f, -0.000000f, -1.000000f, 0.222521f, + -0.974928f, 0.433884f, -0.900969f, 0.623490f, -0.781832f, 0.781832f, -0.623490f, + 0.900969f, -0.433884f, 0.974928f, -0.222521f, 1.000000f, -0.000000f, 0.974928f, + 0.222521f, 0.900969f, 0.433884f, +}; const FLOAT64 iusace_twiddle_table_3pi[1155] = { 0.00000000000000000000, 0.00000000000000000000, 0.00000000000000000000, 0.00000000000000000000, -0.01636173162648678000, -0.03271908282177613700, diff --git a/encoder/iusace_rom.h b/encoder/iusace_rom.h index f927366..ca659b0 100644 --- a/encoder/iusace_rom.h +++ b/encoder/iusace_rom.h @@ -19,7 +19,6 @@ */ #pragma once -extern const UWORD32 iusace_sampl_freq_table[]; extern const FLOAT64 iusace_twiddle_table_fft_32x32[514]; extern const FLOAT64 iusace_twiddle_table_3pr[1155]; extern const FLOAT64 iusace_twiddle_table_3pi[1155]; @@ -28,3 +27,104 @@ extern const FLOAT64 iusace_twiddle_cos_2048[1024]; extern const FLOAT32 ia_fft_twiddle_table_float[514]; extern const FLOAT32 ia_mixed_rad_twiddle_cos[16384]; extern const FLOAT32 ia_mixed_rad_twiddle_sin[16384]; + +#define WIN_LEN_1024 1024 +#define WIN_LEN_768 768 +#define WIN_LEN_128 128 +#define WIN_LEN_256 256 +#define WIN_LEN_192 192 +#define WIN_LEN_96 96 + +extern const FLOAT32 iusace_iir_hipass_coeffs[BLK_SWITCH_FILT_LEN]; +extern const WORD32 iusace_suggested_grouping_table[MAX_SHORT_WINDOWS][MAXIMUM_NO_OF_GROUPS]; +extern const WORD32 iusace_synchronized_block_types[4][4]; + +extern const FLOAT32 iusace_gamma_table[ORDER + 1]; +extern const FLOAT32 iusace_chebyshev_polyn_grid[101]; + +extern const UWORD32 iusace_sampl_freq_idx_table[32]; +extern const WORD32 iusace_bandwidth_table[8][2]; + +extern const WORD32 iusace_huffman_code_table[121][2]; + +extern const FLOAT64 iusace_pre_post_twid_cos_2048[512]; +extern const FLOAT64 iusace_pre_post_twid_sin_2048[512]; +extern const FLOAT64 iexheaac_pre_post_twid_cos_1536[384]; +extern const FLOAT64 iexheaac_pre_post_twid_sin_1536[384]; +extern const FLOAT64 iusace_pre_post_twid_cos_256[64]; +extern const FLOAT64 iusace_pre_post_twid_sin_256[64]; +extern const FLOAT64 iexheaac_pre_post_twid_cos_192[48]; +extern const FLOAT64 iexheaac_pre_post_twid_sin_192[48]; +extern const FLOAT64 iusace_kbd_win1024[1024]; +extern const FLOAT64 iusace_kbd_win256[256]; +extern const FLOAT64 iusace_kbd_win128[128]; + +extern const FLOAT64 iexheaac_kbd_win_768[768]; +extern const FLOAT64 iexheaac_kbd_win_192[192]; +extern const FLOAT64 iexheaac_kbd_win_96[96]; + +extern const FLOAT64 iusace_sine_win_1024[1024]; +extern const FLOAT64 iexheaac_sine_win_768[768]; +extern const FLOAT64 iusace_sine_win_256[256]; +extern const FLOAT64 iusace_sine_win_128[128]; +extern const FLOAT64 iexheaac_sine_win_192[192]; +extern const FLOAT64 iexheaac_sine_win_96[96]; + +extern const UWORD16 iusace_ari_cf_r[3][4]; +extern const UWORD16 iusace_ari_lookup_m[742]; +extern const UWORD32 iusace_ari_hash_m[742]; +extern const UWORD8 iusace_ari_hash_m_lsb[742]; +extern const UWORD16 iusace_ari_cf_m[64][17]; + +extern const FLOAT32 iusace_pre_post_twid_cos_sin_512[4][512]; +extern const FLOAT32 iusace_pre_post_twid_cos_sin_256[4][256]; +extern const FLOAT32 iusace_pre_post_twid_cos_sin_128[4][128]; +extern const FLOAT32 iusace_pre_post_twid_cos_sin_64[4][64]; +extern const FLOAT32 iusace_pre_post_twid_cos_sin_32[4][32]; + +extern const FLOAT64 iusace_pow_table[9000]; + +extern const FLOAT64 iusace_mdst_fcoeff_long_sin[]; +extern const FLOAT64 iusace_mdst_fcoeff_long_kbd[]; +extern const FLOAT64 iusace_mdst_fcoeff_long_sin_kbd[]; +extern const FLOAT64 iusace_mdst_fcoeff_long_kbd_sin[]; +extern const FLOAT64 *const iusace_mdst_fcoeff_longshort_curr[2][2]; + +extern const FLOAT64 iusace_mdst_fcoeff_start_sin[]; +extern const FLOAT64 iusace_mdst_fcoeff_start_kbd[]; +extern const FLOAT64 iusace_mdst_fcoeff_start_sin_kbd[]; +extern const FLOAT64 iusace_mdst_fcoeff_start_kbd_sin[]; + +extern const FLOAT64 *const iusace_mdst_fcoeff_start_curr[2][2]; + +extern const FLOAT64 iusace_mdst_fcoeff_stop_sin[]; +extern const FLOAT64 iusace_mdst_fcoeff_stop_kbd[]; +extern const FLOAT64 iusace_mdst_fcoeff_stop_sin_kbd[]; +extern const FLOAT64 iusace_mdst_fcoeff_stop_kbd_sin[]; + +extern const FLOAT64 *const iusace_mdst_fcoeff_stop_cur[2][2]; + +extern const FLOAT64 iusace_mdst_fcoeff_stopstart_sin[]; +extern const FLOAT64 iusace_mdst_fcoeff_stopstart_kbd[]; +extern const FLOAT64 iusace_mdst_fcoeff_stopstart_sin_kbd[]; +extern const FLOAT64 iusace_mdst_fcoeff_stopstart_kbd_sin[]; + +extern const FLOAT64 *const iusace_mdst_fcoeff_stopstart_cur[2][2]; + +extern const FLOAT64 iusace_mdst_fcoeff_l_s_start_left_sin[]; +extern const FLOAT64 iusace_mdst_fcoeff_l_s_start_left_kbd[]; + +extern const FLOAT64 iusace_mdst_fcoeff_stop_stopstart_left_sin[]; +extern const FLOAT64 iusace_mdst_fcoeff_stop_stopstart_left_kbd[]; + +extern const FLOAT64 *const iusace_mdst_fcoeff_l_s_start_left_prev[2]; + +extern const FLOAT64 *const iusace_mdst_fcoeff_stop_stopstart_left_prev[2]; + +extern const FLOAT32 ia_rad_3_fft_twiddle_re[1155]; + +extern const FLOAT32 ia_rad_3_fft_twiddle_im[1155]; + +extern const FLOAT32 ia_fft_mix_rad_twid_tbl_336[564]; + +extern const FLOAT32 ia_fft_mix_rad_twid_tbl_168[276]; diff --git a/encoder/iusace_signal_classifier.h b/encoder/iusace_signal_classifier.h new file mode 100644 index 0000000..6b18997 --- /dev/null +++ b/encoder/iusace_signal_classifier.h @@ -0,0 +1,152 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +#define FD_MODE 2 +#define TD_MODE 0 +#define MIN_POW -200 +#define INDEXOFLOWFREQUENCY 160 + +#define NFRAMEAHEAD 1 +#define AVE_TONAL_LENGTH 100 +#define AVE_TONAL_LENGTH_SHORT 10 +#define SPECTRAL_TILT_LENGTH 80 +#define SPECTRAL_TILT_LENGTH_SHORT 20 +#define SMOOTHING_LENGTH 100 + +#define NO_BORDER 0 +#define BORDER_MUSIC_SPEECH 1 +#define BORDER_MUSIC_SPEECH_DEFINITE 2 +#define BORDER_SPEECH_MUSIC 3 +#define BORDER_SPEECH_MUSIC_DEFINITE 4 + +#define TBD 0 +#define SPEECH_DEFINITE 1 +#define SPEECH 2 +#define MUSIC_DEFINITE 3 +#define MUSIC 4 +#define LOG_1024_BASE_10 3.01029995664f +#define LOG_768_BASE_10 (2.88536122003f) + +typedef struct { + WORD32 smoothing_result_buf[100]; /** +#include +#include "ixheaac_type_def.h" +#include "ixheaace_adjust_threshold_data.h" +#include "iusace_bitbuffer.h" + +/* DRC */ +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" +#include "impd_drc_uni_drc_eq.h" +#include "impd_drc_uni_drc_filter_bank.h" +#include "impd_drc_gain_enc.h" +#include "impd_drc_struct_def.h" + +#include "iusace_cnst.h" +#include "iusace_tns_usac.h" +#include "iusace_psy_mod.h" +#include "iusace_tns_usac.h" +#include "iusace_config.h" +#include "iusace_fft.h" +#include "iusace_tcx_mdct.h" +#include "iusace_arith_enc.h" +#include "iusace_fd_qc_util.h" +#include "iusace_fd_quant.h" +#include "iusace_block_switch_const.h" +#include "iusace_block_switch_struct_def.h" +#include "iusace_ms.h" +#include "iusace_signal_classifier.h" +#include "ixheaace_sbr_header.h" +#include "ixheaace_config.h" +#include "ixheaace_asc_write.h" +#include "iusace_main.h" +#include "iusace_lpd_rom.h" +#include "iusace_lpd.h" +#include "iusace_avq_enc.h" +#include "ixheaace_common_utils.h" + +const UWORD32 iusace_pow10_gain_div28[128] = { + 1024, 1112, 1207, 1311, 1423, 1545, 1677, 1821, 1977, + 2146, 2330, 2530, 2747, 2983, 3238, 3516, 3817, 4144, + 4499, 4885, 5304, 5758, 6252, 6788, 7370, 8001, 8687, + 9432, 10240, 11118, 12071, 13105, 14228, 15448, 16772, 18210, + 19770, 21465, 23305, 25302, 27471, 29825, 32382, 35157, 38171, + 41442, 44994, 48851, 53038, 57584, 62519, 67878, 73696, 80012, + 86870, 94316, 102400, 111177, 120706, 131052, 142284, 154480, 167720, + 182096, 197703, 214649, 233047, 253021, 274708, 298254, 323817, 351572, + 381706, 414422, 449943, 488508, 530378, 575838, 625193, 678779, 736958, + 800124, 868703, 943161, 1024000, 1111768, 1207059, 1310517, 1422843, 1544797, + 1677203, 1820958, 1977034, 2146488, 2330466, 2530213, 2747080, 2982536, 3238172, + 3515720, 3817056, 4144220, 4499426, 4885077, 5303782, 5758375, 6251932, 6787792, + 7369581, 8001236, 8687031, 9431606, 10240000, 11117682, 12070591, 13105175, 14228434, + 15447969, 16772032, 18209581, 19770345, 21464883, 23304662, 25302131, 27470805, 29825358, + 32381723, 35157197}; + +static const FLOAT64 iusace_lpc_pre_twid_cos[ORDER + 1] = {1.0, + 0.99969881867944277, + 0.99879545613814691, + 0.99729045666498317, + 0.99518472640441780, + 0.99247953486470630, + 0.98917650991010153, + 0.98527764316379052, + 0.98078527933727178, + 0.97570212991605565, + 0.97003125425052761, + 0.96377606826277584, + 0.95694033551585822, + 0.94952817722361749, + 0.94154406823678738, + 0.93299279849944938, + 0.92387952832938047}; + +static const FLOAT64 iusace_lpc_pre_twid_sin[ORDER + 1] = {0, + 0.024541229205697054, + 0.049067675691753569, + 0.073564563785488826, + 0.098017143048367339, + 0.12241067304257494, + 0.14673047482398086, + 0.17096188429473480, + 0.19509032737506427, + 0.21910124070226658, + 0.24298017568754085, + 0.26671274855909161, + 0.29028467796767482, + 0.31368175059826858, + 0.33688984485751389, + 0.35989503740419343, + 0.38268344246110436}; + +static VOID iusace_lpc_mdct(FLOAT32 *ptr_lpc_coeffs, FLOAT32 *mdct_gains, WORD32 length, + iusace_scratch_mem *pstr_scratch) { + FLOAT32 *in_out = pstr_scratch->p_in_out_tcx; + WORD32 i; + + for (i = 0; i < ORDER + 1; i++) { + in_out[2 * i] = (FLOAT32)(ptr_lpc_coeffs[i] * iusace_lpc_pre_twid_cos[i]); + in_out[2 * i + 1] = (FLOAT32)(-ptr_lpc_coeffs[i] * iusace_lpc_pre_twid_sin[i]); + } + for (; i < length; i++) { + in_out[2 * i] = 0.f; + in_out[2 * i + 1] = 0.f; + } + + iusace_complex_fft(in_out, length, pstr_scratch); + + for (i = 0; i < length >> 1; i++) { + mdct_gains[i] = (FLOAT32)(1.0f / sqrt(in_out[2 * i] * in_out[2 * i] + + in_out[2 * i + 1] * in_out[2 * i + 1])); + } + + return; +} + +UWORD32 iusace_rounded_sqrt(UWORD32 pos_num) { + UWORD32 num = pos_num; + UWORD32 value = 0; + UWORD32 bit_set = 1 << 30; + + while (bit_set > num) { + bit_set >>= 2; + } + while (bit_set) { + if (num >= value + bit_set) { + num -= value + bit_set; + value += bit_set << 1; + } + value >>= 1; + bit_set >>= 2; + } + num = value + 1; + if (num * num - pos_num < pos_num - value * value) { + return num; + } + return value; +} + +static VOID iusace_noise_shaping(FLOAT32 *rr, WORD32 lg, FLOAT32 *gain1, FLOAT32 *gain2) { + WORD32 i, k; + FLOAT32 r, r_prev, g1, g2, a = 0, b = 0; + + k = lg / FDNS_RESOLUTION; + + r_prev = 0; + for (i = 0; i < lg; i++) { + if ((i % k) == 0) { + g1 = gain1[i / k]; + g2 = gain2[i / k]; + + a = 2.0f * g1 * g2 / (g1 + g2); + b = (g2 - g1) / (g1 + g2); + } + + r = a * rr[i] + b * r_prev; + + rr[i] = r; + r_prev = r; + } + + return; +} + +static VOID iusace_pre_shaping(FLOAT32 *rr, WORD32 lg, FLOAT32 *gain1, FLOAT32 *gain2) { + WORD32 i, k; + FLOAT32 r, r_prev, g1, g2, a = 0, b = 0; + + k = lg / FDNS_RESOLUTION; + + r_prev = 0; + for (i = 0; i < lg; i++) { + if ((i % k) == 0) { + g1 = gain1[i / k]; + g2 = gain2[i / k]; + + a = (g1 + g2) / (2.0f * g1 * g2); + b = (g1 - g2) / (2.0f * g1 * g2); + } + + r = a * rr[i] + b * r_prev; + + r_prev = rr[i]; + rr[i] = r; + } + + return; +} + +static VOID iusace_adapt_lo_freq_emph(FLOAT32 *signal, WORD32 length) { + WORD32 i, j, i_max; + FLOAT32 max_energy, factor, temp; + + i_max = length >> 2; + + max_energy = 0.01f; + for (i = 0; i < i_max; i += 8) { + temp = 0.01f; + for (j = i; j < i + 8; j++) { + temp += signal[j] * signal[j]; + } + if (temp > max_energy) { + max_energy = temp; + } + } + + factor = 10.0f; + for (i = 0; i < i_max; i += 8) { + temp = 0.01f; + for (j = i; j < i + 8; j++) { + temp += signal[j] * signal[j]; + } + temp = (FLOAT32)sqrt(sqrt(max_energy / temp)); + if (temp < factor) { + factor = temp; + } + for (j = i; j < i + 8; j++) { + signal[j] *= factor; + } + } + return; +} + +static VOID iusace_adapt_lo_freq_deemph(FLOAT32 *signal, WORD32 length, FLOAT32 *gains) { + WORD32 i, j, i_max; + FLOAT32 max_energy, factor, energy, rm; + + i_max = length >> 2; + + max_energy = 0.01f; + for (i = 0; i < i_max; i += 8) { + energy = 0.01f; + for (j = i; j < i + 8; j++) { + energy += signal[j] * signal[j]; + } + if (energy > max_energy) { + max_energy = energy; + } + } + + factor = 0.1f; + for (i = 0; i < i_max; i += 8) { + energy = 0.01f; + for (j = i; j < i + 8; j++) { + energy += signal[j] * signal[j]; + } + + rm = (FLOAT32)sqrt(energy / max_energy); + if (rm > factor) { + factor = rm; + } + for (j = i; j < i + 8; j++) { + signal[j] *= factor; + } + gains[i / 8] = factor; + } + + return; +} + +VOID iusace_tcx_fac_encode(ia_usac_data_struct *usac_data, FLOAT32 *lpc_coeffs, + FLOAT32 *lpc_coeffs_quant, FLOAT32 *speech, WORD32 frame_len, + WORD32 num_bits_per_supfrm, ia_usac_lpd_state_struct *lpd_state, + WORD32 *params, WORD32 *n_param, WORD32 ch_idx, WORD32 k_idx) { + ia_usac_td_encoder_struct *st = usac_data->td_encoder[ch_idx]; + iusace_scratch_mem *pstr_scratch = &usac_data->str_scratch; + FLOAT32 *weighted_sig = &pstr_scratch->p_wsig_buf[k_idx * st->len_subfrm]; + FLOAT32 *wsynth = pstr_scratch->p_wsyn_tcx_buf; + FLOAT32 *synth = pstr_scratch->p_synth_tcx_buf; + WORD32 i, k, n, mode, i_subfr, lg, lext, index, target_bits; + FLOAT32 tmp, gain, fac_ns, energy, gain_tcx, nsfill_en_thres; + FLOAT32 *ptr_lp_flt_coeffs, lp_flt_coeffs[ORDER + 1]; + const FLOAT32 *sine_window_prev, *sine_window; + FLOAT32 mem_tcx_q; + FLOAT32 *xn; + FLOAT32 *xn1 = pstr_scratch->p_xn1_tcx; + FLOAT32 *xn_buf = pstr_scratch->p_xn_buf_tcx; + FLOAT32 *x = pstr_scratch->p_x_tcx; + FLOAT32 *x_tmp = pstr_scratch->p_x_tmp_tcx; + FLOAT32 *en = pstr_scratch->p_en_tcx; + FLOAT32 sq_gain; + FLOAT32 gain_prev, gain_next; + FLOAT32 *alfd_gains = pstr_scratch->p_alfd_gains_tcx; + FLOAT32 *sq_enc = pstr_scratch->p_sq_enc_tcx; + WORD32 *sq_quant = pstr_scratch->p_sq_quant_tcx; + FLOAT32 sq_err_energy; + WORD32 max_k; + FLOAT32 *gain1 = pstr_scratch->p_gain1_tcx; + FLOAT32 *gain2 = pstr_scratch->p_gain2_tcx; + FLOAT32 *facelp = pstr_scratch->p_facelp_tcx; + FLOAT32 *xn2 = pstr_scratch->p_xn2_tcx; + FLOAT32 *fac_window = pstr_scratch->p_fac_window_tcx; + FLOAT32 *x1 = pstr_scratch->p_x1_tcx; + FLOAT32 *x2 = pstr_scratch->p_x2_tcx; + WORD32 *y = pstr_scratch->p_y_tcx; + + WORD32 TTT; + FLOAT32 corr = 0; + WORD32 len_subfrm = st->len_subfrm; + WORD32 fac_length = len_subfrm >> 1; + WORD32 fac_len_prev, fac_len; + + if (frame_len == 4 * st->len_subfrm) { + if (st->last_was_short) { + fac_len_prev = (st->len_frame) / 16; + } else { + fac_len_prev = st->len_subfrm / 2; + } + if (st->next_is_short) { + fac_len = (st->len_frame) / 16; + } else { + fac_len = st->len_subfrm / 2; + } + } else if (frame_len == 2 * st->len_subfrm) { + if (k_idx == 0 && st->last_was_short) { + fac_len_prev = (st->len_frame) / 16; + } else { + fac_len_prev = st->len_subfrm / 2; + } + if (k_idx == 2 && st->next_is_short) { + fac_len = (st->len_frame) / 16; + } else { + fac_len = st->len_subfrm / 2; + } + } else { + if (k_idx == 0 && st->last_was_short) { + fac_len_prev = (st->len_frame) / 16; + } else { + fac_len_prev = st->len_subfrm / 2; + } + if (k_idx == 3 && st->next_is_short) { + fac_len = (st->len_frame) / 16; + } else { + fac_len = st->len_subfrm / 2; + } + } + + memset(xn_buf, 0, (128 + frame_len + 128) * sizeof(FLOAT32)); + + mode = frame_len / len_subfrm; + + if (mode > 2) { + mode = 3; + } + + if (lpd_state->mode == 0) { + params += fac_len_prev; + } + switch (fac_len_prev) { + case 64: + sine_window_prev = iusace_sin_window_128; + break; + default: + sine_window_prev = iusace_sin_window_256; + break; + } + switch (fac_len) { + case 64: + sine_window = iusace_sin_window_128; + break; + default: + sine_window = iusace_sin_window_256; + break; + } + + lg = frame_len; + lext = fac_length; + xn = xn_buf + fac_length; + + *n_param = lg; + + target_bits = num_bits_per_supfrm - 10; + + for (i = 0; i < fac_length; i++) { + xn_buf[i] = lpd_state->tcx_mem[i + 128 - fac_length]; + } + + memcpy(xn, speech, (frame_len + fac_length) * sizeof(FLOAT32)); + + tmp = xn[-1]; + + iusace_apply_deemph(xn, TILT_FAC, frame_len, &tmp); + + memcpy(lpd_state->tcx_mem, &xn[frame_len - 128], 128 * sizeof(FLOAT32)); + + memcpy(&xn[frame_len], &speech[frame_len], lext * sizeof(FLOAT32)); + iusace_apply_deemph(&xn[frame_len], TILT_FAC, lext, &tmp); + + for (i = 0; i < ORDER + fac_len_prev; i++) { + xn1[i] = xn_buf[fac_length - ORDER + i]; + } + for (i = 0; i < ORDER + fac_len; i++) { + xn2[i] = xn_buf[frame_len - ORDER + i]; + } + + if (lpd_state->mode >= -1) { + for (i = 0; i < fac_length - fac_len_prev; i++) { + xn_buf[i] = 0.0f; + } + for (i = fac_length - fac_len_prev; i < (fac_length + fac_len_prev); i++) { + xn_buf[i] *= sine_window_prev[i - fac_length + fac_len_prev]; + } + for (i = 0; i < (2 * fac_len); i++) { + xn_buf[frame_len + fac_length - fac_len + i] *= sine_window[(2 * fac_len) - 1 - i]; + } + for (i = 0; i < fac_length - fac_len; i++) { + xn_buf[frame_len + fac_length + fac_len + i] = 0.0f; + } + } + + iusace_tcx_mdct_main(xn_buf, x, (2 * fac_length), frame_len - (2 * fac_length), + (2 * fac_length), pstr_scratch); + + iusace_get_weighted_lpc(lpc_coeffs_quant + (ORDER + 1), lp_flt_coeffs); + iusace_lpc_mdct(lp_flt_coeffs, gain1, ((FDNS_RESOLUTION * len_subfrm) / LEN_FRAME) << 1, + pstr_scratch); + + iusace_get_weighted_lpc(lpc_coeffs_quant + (2 * (ORDER + 1)), lp_flt_coeffs); + iusace_lpc_mdct(lp_flt_coeffs, gain2, ((FDNS_RESOLUTION * len_subfrm) / LEN_FRAME) << 1, + pstr_scratch); + + iusace_pre_shaping(x, lg, gain1, gain2); + + for (i = 0; i < lg; i++) { + x_tmp[i] = x[i]; + } + + iusace_adapt_lo_freq_emph(x, lg); + + sq_gain = iusace_calc_sq_gain(x, target_bits, lg, pstr_scratch->p_sq_gain_en); + + for (i = 0; i < lg; i++) { + sq_enc[i] = x[i] / sq_gain; + + if (sq_enc[i] > 0.f) + sq_quant[i] = ((WORD32)(0.5f + sq_enc[i])); + else + sq_quant[i] = ((WORD32)(-0.5f + sq_enc[i])); + } + + for (i = 0; i < lg; i++) { + params[i + 2] = sq_quant[i]; + x[i] = (FLOAT32)sq_quant[i]; + } + + for (i = 0; i < lg; i++) { + en[i] = x[i] * x[i]; + } + if (mode == 3) { + tmp = 0.9441f; + } else if (mode == 2) { + tmp = 0.8913f; + } else { + tmp = 0.7943f; + } + energy = 0.0f; + for (i = 0; i < lg; i++) { + if (en[i] > energy) { + energy = en[i]; + } + en[i] = energy; + energy *= tmp; + } + energy = 0.0f; + for (i = lg - 1; i >= 0; i--) { + if (en[i] > energy) { + energy = en[i]; + } + en[i] = energy; + energy *= tmp; + } + + nsfill_en_thres = 0.707f; + + tmp = 0.0625f; + k = 1; + for (i = 0; i < lg; i++) { + if (en[i] <= nsfill_en_thres) { + tmp += sq_enc[i] * sq_enc[i]; + k++; + } + } + + iusace_adapt_lo_freq_deemph(x, lg, alfd_gains); + + energy = 1e-6f; + for (i = 0; i < lg; i++) { + corr += x_tmp[i] * x[i]; + energy += x[i] * x[i]; + } + gain_tcx = (corr / energy); + + if (gain_tcx == 0.0f) { + gain_tcx = sq_gain; + } + + energy = 0.0001f; + for (i = 0; i < lg; i++) { + tmp = x_tmp[i] - gain_tcx * x[i]; + energy += tmp * tmp; + } + + tmp = (FLOAT32)sqrt((energy * (2.0f / (FLOAT32)lg)) / (FLOAT32)lg); + + for (i = 0; i < frame_len; i++) { + wsynth[i] = weighted_sig[i] + tmp; + } + + energy = 0.01f; + for (i = 0; i < lg; i++) { + energy += x[i] * x[i]; + } + + tmp = (FLOAT32)(2.0f * sqrt(energy) / (FLOAT32)lg); + gain = gain_tcx * tmp; + + index = (WORD32)floor(0.5f + (28.0f * (FLOAT32)log10(gain))); + if (index < 0) { + index = 0; + } + if (index > 127) { + index = 127; + } + params[1] = index; + + gain_tcx = (FLOAT32)pow(10.0f, ((FLOAT32)index) / 28.0f) / tmp; + st->gain_tcx = gain_tcx; + + sq_err_energy = 0.f; + n = 0; + for (k = lg / 2; k < lg;) { + tmp = 0.f; + + max_k = MIN(lg, k + 8); + for (i = k; i < max_k; i++) { + tmp += (FLOAT32)sq_quant[i] * sq_quant[i]; + } + if (tmp == 0.f) { + tmp = 0.f; + for (i = k; i < max_k; i++) { + tmp += sq_enc[i] * sq_enc[i]; + } + + sq_err_energy += (FLOAT32)log10((tmp / (FLOAT64)8) + 0.000000001); + n += 1; + } + k = max_k; + } + if (n > 0) { + fac_ns = (FLOAT32)pow(10., sq_err_energy / (FLOAT64)(2 * n)); + } else { + fac_ns = 0.f; + } + + tmp = 8.0f - (16.0f * fac_ns); + + index = (WORD32)floor(tmp + 0.5); + if (index < 0) { + index = 0; + } + if (index > 7) { + index = 7; + } + + params[0] = index; + + iusace_noise_shaping(x, lg, gain1, gain2); + + iusace_tcx_imdct(x, xn_buf, (2 * fac_length), frame_len - (2 * fac_length), (2 * fac_length), + pstr_scratch); + for (i = 0; i < frame_len + (2 * fac_length); i++) { + xn_buf[i] = xn_buf[i] * (2.0f / lg); + } + + for (i = 0; i < fac_len_prev; i++) { + fac_window[i] = sine_window_prev[i] * sine_window_prev[(2 * fac_len_prev) - 1 - i]; + fac_window[fac_len_prev + i] = + 1.0f - (sine_window_prev[fac_len_prev + i] * sine_window_prev[fac_len_prev + i]); + } + + for (i = 0; i < fac_len_prev; i++) { + xn1[ORDER + i] -= sq_gain * xn_buf[fac_length + i] * sine_window_prev[fac_len_prev + i]; + } + for (i = 0; i < fac_len; i++) { + xn2[ORDER + i] -= sq_gain * xn_buf[i + frame_len] * sine_window[(2 * fac_len) - 1 - i]; + } + + for (i = 0; i < ORDER; i++) { + xn1[i] -= lpd_state->tcx_quant[1 + 128 - ORDER + i]; + xn2[i] -= sq_gain * xn_buf[frame_len - ORDER + i]; + } + + for (i = 0; i < fac_len_prev; i++) { + facelp[i] = lpd_state->tcx_quant[1 + 128 + i] * fac_window[fac_len_prev + i] + + lpd_state->tcx_quant[1 + 128 - 1 - i] * fac_window[fac_len_prev - 1 - i]; + } + + energy = 0.0f; + for (i = 0; i < fac_len_prev; i++) energy += xn1[ORDER + i] * xn1[ORDER + i]; + energy *= 2.0f; + tmp = 0.0f; + for (i = 0; i < fac_len_prev; i++) tmp += facelp[i] * facelp[i]; + if (tmp > energy) + gain = (FLOAT32)sqrt(energy / tmp); + else + gain = 1.0f; + + for (i = 0; i < fac_len_prev; i++) { + xn1[ORDER + i] -= gain * facelp[i]; + } + + iusace_get_weighted_lpc(lpc_coeffs_quant + (ORDER + 1), lp_flt_coeffs); + iusace_compute_lp_residual(lp_flt_coeffs, xn1 + ORDER, x1, fac_len_prev); + + iusace_get_weighted_lpc(lpc_coeffs_quant + (2 * (ORDER + 1)), lp_flt_coeffs); + iusace_compute_lp_residual(lp_flt_coeffs, xn2 + ORDER, x2, fac_len); + + iusace_tcx_mdct(x1, x1, fac_len_prev, pstr_scratch); + iusace_tcx_mdct(x2, x2, fac_len, pstr_scratch); + + gain_prev = (FLOAT32)(sq_gain * 0.5f * sqrt(((FLOAT32)fac_len_prev) / (FLOAT32)frame_len)); + gain_next = (FLOAT32)(sq_gain * 0.5f * sqrt(((FLOAT32)fac_len) / (FLOAT32)frame_len)); + + for (i = 0; i < fac_len_prev; i++) { + x1[i] /= gain_prev; + } + for (i = 0; i < fac_len; i++) { + x2[i] /= gain_next; + } + for (i = 0; i < fac_len_prev / 4; i++) { + k = i * lg / (8 * fac_len_prev); + x1[i] /= alfd_gains[k]; + } + for (i = 0; i < fac_len / 4; i++) { + k = i * lg / (8 * fac_len); + x2[i] /= alfd_gains[k]; + } + + for (i = 0; i < fac_len; i += 8) { + iusace_find_nearest_neighbor(&x2[i], &y[i]); + } + for (i = 0; i < fac_len; i++) { + lpd_state->avq_params[i] = y[i]; + x2[i] = (FLOAT32)y[i]; + } + + for (i = 0; i < fac_len_prev; i += 8) { + iusace_find_nearest_neighbor(&x1[i], &y[i]); + } + + for (i = 0; i < fac_len_prev; i++) { + x1[i] = (FLOAT32)y[i]; + } + + gain_prev = (FLOAT32)(gain_tcx * 0.5f * sqrt(((FLOAT32)fac_len_prev) / (FLOAT32)frame_len)); + gain_next = (FLOAT32)(gain_tcx * 0.5f * sqrt(((FLOAT32)fac_len) / (FLOAT32)frame_len)); + + for (i = 0; i < fac_len_prev; i++) { + x1[i] *= gain_prev; + } + for (i = 0; i < fac_len; i++) { + x2[i] *= gain_next; + } + for (i = 0; i < fac_len_prev >> 2; i++) { + k = i * lg / (fac_len_prev << 3); + x1[i] *= alfd_gains[k]; + } + for (i = 0; i < fac_len >> 2; i++) { + k = i * lg / (fac_len << 3); + x2[i] *= alfd_gains[k]; + } + iusace_tcx_mdct(x1, xn1, fac_len_prev, pstr_scratch); + iusace_tcx_mdct(x2, xn2, fac_len, pstr_scratch); + + FLOAT32 coeff1 = (2.0f / (FLOAT32)fac_len_prev), coeff2 = (2.0f / (FLOAT32)fac_len); + + for (i = 0; i < fac_len_prev; i++) { + xn1[i] = xn1[i] * coeff1; + } + + for (i = 0; i < fac_len; i++) { + xn2[i] = xn2[i] * coeff2; + } + + memset(xn1 + fac_len_prev, 0, fac_len_prev * sizeof(FLOAT32)); + memset(xn2 + fac_len, 0, fac_len * sizeof(FLOAT32)); + + iusace_get_weighted_lpc(lpc_coeffs_quant + (ORDER + 1), lp_flt_coeffs); + iusace_synthesis_tool_float(lp_flt_coeffs, xn1, xn1, 2 * fac_len_prev, xn1 + fac_len_prev, + pstr_scratch->p_buf_synthesis_tool); + + iusace_get_weighted_lpc(lpc_coeffs_quant + (2 * (ORDER + 1)), lp_flt_coeffs); + iusace_synthesis_tool_float(lp_flt_coeffs, xn2, xn2, fac_len, xn2 + fac_len, + pstr_scratch->p_buf_synthesis_tool); + + for (i = 0; i < fac_len_prev; i++) { + xn1[i] += facelp[i]; + } + + for (i = 0; i < frame_len + (fac_length << 1); i++) { + xn_buf[i] *= gain_tcx; + } + + if (lpd_state->mode >= -1) { + for (i = 0; i < (2 * fac_len_prev); i++) { + xn_buf[i + fac_length - fac_len_prev] *= sine_window_prev[i]; + } + for (i = 0; i < fac_length - fac_len_prev; i++) { + xn_buf[i] = 0.0f; + } + } + for (i = 0; i < (2 * fac_len); i++) { + xn_buf[i + frame_len + fac_length - fac_len] *= sine_window[(2 * fac_len) - 1 - i]; + } + for (i = 0; i < fac_length - fac_len; i++) { + xn_buf[i + frame_len + fac_length + fac_len] = 0.0f; + } + + if (lpd_state->mode != 0) { + for (i = 0; i < (2 * fac_length); i++) { + xn_buf[i] += lpd_state->tcx_quant[1 + 128 - fac_length + i]; + } + + mem_tcx_q = lpd_state->tcx_quant[128 - fac_length]; + } else { + for (i = 0; i < fac_len_prev; i++) { + params[i - fac_len_prev] = y[i]; + } + + for (i = 0; i < (2 * fac_len_prev); i++) { + xn_buf[i + fac_length] += xn1[i]; + } + mem_tcx_q = lpd_state->tcx_quant[128]; + } + + memcpy(lpd_state->tcx_quant, xn_buf + frame_len + fac_length - 128 - 1, + (1 + 256) * sizeof(FLOAT32)); + + for (i = 0; i < fac_len; i++) { + xn_buf[i + frame_len + (fac_length - fac_len)] += xn2[i]; + } + + if (lpd_state->mode > 0) { + iusace_apply_preemph(xn_buf, TILT_FAC, fac_length, &mem_tcx_q); + + ptr_lp_flt_coeffs = lpd_state->lpc_coeffs_quant; + + TTT = fac_length % LEN_SUBFR; + if (TTT != 0) { + memcpy(&(lpd_state->synth[ORDER + 128 - fac_length]), &xn_buf[0], TTT * sizeof(FLOAT32)); + iusace_compute_lp_residual(ptr_lp_flt_coeffs, &(lpd_state->synth[ORDER + 128 - fac_length]), + &(lpd_state->acelp_exc[(2 * len_subfrm) - fac_length]), TTT); + + ptr_lp_flt_coeffs += (ORDER + 1); + } + + for (i_subfr = TTT; i_subfr < fac_length; i_subfr += LEN_SUBFR) { + memcpy(&(lpd_state->synth[ORDER + 128 - fac_length + i_subfr]), &xn_buf[i_subfr], + LEN_SUBFR * sizeof(FLOAT32)); + iusace_compute_lp_residual( + ptr_lp_flt_coeffs, &(lpd_state->synth[ORDER + 128 - fac_length + i_subfr]), + &(lpd_state->acelp_exc[(2 * len_subfrm) - fac_length + i_subfr]), LEN_SUBFR); + ptr_lp_flt_coeffs += (ORDER + 1); + } + + ptr_lp_flt_coeffs = lpd_state->lpc_coeffs; + for (i_subfr = 0; i_subfr < fac_length; i_subfr += LEN_SUBFR) { + iusace_get_weighted_lpc(ptr_lp_flt_coeffs, lp_flt_coeffs); + iusace_compute_lp_residual(lp_flt_coeffs, + &(lpd_state->synth[ORDER + 128 - fac_length + i_subfr]), + &(lpd_state->wsynth[1 + 128 - fac_length + i_subfr]), LEN_SUBFR); + ptr_lp_flt_coeffs += (ORDER + 1); + } + tmp = lpd_state->wsynth[0 + 128 - fac_length]; + iusace_apply_deemph(&(lpd_state->wsynth[1 + 128 - fac_length]), TILT_FAC, fac_length, &tmp); + } + + k = ((frame_len / LEN_SUBFR) - 2) * (ORDER + 1); + memcpy(lpd_state->lpc_coeffs, lpc_coeffs + k, 2 * (ORDER + 1) * sizeof(FLOAT32)); + + memcpy(lpd_state->lpc_coeffs_quant, lpc_coeffs_quant + (2 * (ORDER + 1)), + (ORDER + 1) * sizeof(FLOAT32)); + memcpy(lpd_state->lpc_coeffs_quant + (ORDER + 1), lpd_state->lpc_coeffs_quant, + (ORDER + 1) * sizeof(FLOAT32)); + + memcpy(synth - 128, &(lpd_state->synth[ORDER]), 128 * sizeof(FLOAT32)); + lpd_state->tcx_fac = xn[frame_len - 1]; + + iusace_apply_preemph(xn, TILT_FAC, frame_len, &mem_tcx_q); + for (i_subfr = 0; i_subfr < frame_len; i_subfr += LEN_SUBFR) { + memcpy(&synth[i_subfr], &xn[i_subfr], LEN_SUBFR * sizeof(FLOAT32)); + iusace_compute_lp_residual(lpc_coeffs_quant + (2 * (ORDER + 1)), &synth[i_subfr], + &xn[i_subfr], LEN_SUBFR); + } + memcpy(lpd_state->synth, synth + frame_len - (ORDER + 128), (ORDER + 128) * sizeof(FLOAT32)); + + if (frame_len == len_subfrm) { + memcpy(x, lpd_state->acelp_exc + len_subfrm, len_subfrm * sizeof(FLOAT32)); + memcpy(lpd_state->acelp_exc, x, len_subfrm * sizeof(FLOAT32)); + memcpy(lpd_state->acelp_exc + len_subfrm, xn, len_subfrm * sizeof(FLOAT32)); + } else { + memcpy(lpd_state->acelp_exc, xn + frame_len - (2 * len_subfrm), + 2 * len_subfrm * sizeof(FLOAT32)); + } + + memcpy(wsynth - 128, &(lpd_state->wsynth[1]), 128 * sizeof(FLOAT32)); + + ptr_lp_flt_coeffs = lpc_coeffs; + for (i_subfr = 0; i_subfr < frame_len; i_subfr += LEN_SUBFR) { + iusace_get_weighted_lpc(ptr_lp_flt_coeffs, lp_flt_coeffs); + iusace_compute_lp_residual(lp_flt_coeffs, &synth[i_subfr], &wsynth[i_subfr], LEN_SUBFR); + ptr_lp_flt_coeffs += (ORDER + 1); + } + tmp = wsynth[-1]; + iusace_apply_deemph(wsynth, TILT_FAC, frame_len, &tmp); + + memcpy(lpd_state->wsynth, wsynth + frame_len - (1 + 128), (1 + 128) * sizeof(FLOAT32)); + + lpd_state->mode = mode; + + lpd_state->num_bits = 10 + target_bits; + + return; +} diff --git a/encoder/iusace_tcx_mdct.c b/encoder/iusace_tcx_mdct.c new file mode 100644 index 0000000..10ed237 --- /dev/null +++ b/encoder/iusace_tcx_mdct.c @@ -0,0 +1,186 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include "ixheaac_type_def.h" +#include "iusace_block_switch_const.h" +#include "iusace_cnst.h" +#include "iusace_rom.h" +#include "iusace_bitbuffer.h" + +/* DRC */ +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" +#include "impd_drc_uni_drc_eq.h" +#include "impd_drc_uni_drc_filter_bank.h" +#include "impd_drc_gain_enc.h" +#include "impd_drc_struct_def.h" + +#include "iusace_tns_usac.h" +#include "iusace_psy_mod.h" +#include "iusace_tns_usac.h" +#include "iusace_config.h" +#include "iusace_fft.h" +#include "iusace_tcx_mdct.h" + +VOID iusace_tcx_mdct_main(FLOAT32 *ptr_in, FLOAT32 *ptr_out, WORD32 l, WORD32 m, WORD32 r, + iusace_scratch_mem *pstr_scratch) { + WORD32 length = l / 2 + m + r / 2; + FLOAT32 *input = pstr_scratch->p_tcx_input; + WORD32 i; + + for (i = 0; i < m / 2; i++) { + input[m / 2 + r / 2 + i] = -ptr_in[l + m / 2 - 1 - i]; + } + for (i = 0; i < l / 2; i++) { + input[m / 2 + r / 2 + m / 2 + i] = ptr_in[i] - ptr_in[l - 1 - i]; + } + for (i = 0; i < m / 2; i++) { + input[m / 2 + r / 2 - 1 - i] = -ptr_in[l + m / 2 + i]; + } + for (i = 0; i < r / 2; i++) { + input[m / 2 + r / 2 - 1 - m / 2 - i] = -ptr_in[l + m + i] - ptr_in[l + m + r - 1 - i]; + } + + iusace_tcx_mdct(input, ptr_out, length, pstr_scratch); + + return; +} + +VOID iusace_tcx_imdct(FLOAT32 *ptr_in, FLOAT32 *ptr_out, WORD32 l, WORD32 m, WORD32 r, + iusace_scratch_mem *pstr_scratch) { + WORD32 length = l / 2 + m + r / 2; + FLOAT32 *output = pstr_scratch->p_tcx_output; + iusace_tcx_mdct(ptr_in, output, length, pstr_scratch); + + WORD32 i; + + for (i = 0; i < m / 2; i++) { + ptr_out[l + m / 2 - 1 - i] = -1.0f * output[m / 2 + r / 2 + i]; + } + for (i = 0; i < l / 2; i++) { + ptr_out[i] = output[m / 2 + r / 2 + m / 2 + i]; + ptr_out[l - 1 - i] = -1.0f * output[m / 2 + r / 2 + m / 2 + i]; + } + for (i = 0; i < m / 2; i++) { + ptr_out[l + m / 2 + i] = -1.0f * output[m / 2 + r / 2 - 1 - i]; + } + for (i = 0; i < r / 2; i++) { + ptr_out[l + m + i] = -1.0f * output[m / 2 + r / 2 - 1 - m / 2 - i]; + ptr_out[l + m + r - 1 - i] = -1.0f * output[m / 2 + r / 2 - 1 - m / 2 - i]; + } + return; +} + +static VOID iusace_get_pre_post_twid(FLOAT32 **ptr_pre_twid_re, FLOAT32 **ptr_pre_twid_im, + FLOAT32 **ptr_post_twid_re, FLOAT32 **ptr_post_twid_im, + WORD32 length) { + switch (length) { + case 512: + *ptr_pre_twid_re = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_256[0][0]; + *ptr_pre_twid_im = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_256[1][0]; + *ptr_post_twid_re = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_256[2][0]; + *ptr_post_twid_im = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_256[3][0]; + break; + case 256: + *ptr_pre_twid_re = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_128[0][0]; + *ptr_pre_twid_im = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_128[1][0]; + *ptr_post_twid_re = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_128[2][0]; + *ptr_post_twid_im = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_128[3][0]; + break; + case 128: + *ptr_pre_twid_re = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_64[0][0]; + *ptr_pre_twid_im = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_64[1][0]; + *ptr_post_twid_re = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_64[2][0]; + *ptr_post_twid_im = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_64[3][0]; + break; + case 64: + *ptr_pre_twid_re = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_32[0][0]; + *ptr_pre_twid_im = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_32[1][0]; + *ptr_post_twid_re = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_32[2][0]; + *ptr_post_twid_im = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_32[3][0]; + break; + default: + *ptr_pre_twid_re = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_512[0][0]; + *ptr_pre_twid_im = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_512[1][0]; + *ptr_post_twid_re = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_512[2][0]; + *ptr_post_twid_im = (FLOAT32 *)&iusace_pre_post_twid_cos_sin_512[3][0]; + } + + return; +} + +static VOID iusace_pre_twid(FLOAT32 *ptr_twid_re, FLOAT32 *ptr_twid_im, FLOAT32 *ptr_in, + WORD32 length) { + WORD32 i; + for (i = 0; i < length; i++) { + FLOAT32 temp = ptr_in[2 * i] * ptr_twid_re[i] - ptr_in[2 * i + 1] * ptr_twid_im[i]; + + ptr_in[2 * i + 1] = ptr_in[2 * i] * ptr_twid_im[i] + ptr_in[2 * i + 1] * ptr_twid_re[i]; + + ptr_in[2 * i] = temp; + } + return; +} + +static VOID iusace_post_twid(FLOAT32 *ptr_twid_re, FLOAT32 *ptr_twid_im, FLOAT32 *ptr_in, + WORD32 length) { + WORD32 i; + for (i = 0; i < length; i++) { + FLOAT32 temp = ptr_in[2 * i] * ptr_twid_re[i] - ptr_in[2 * i + 1] * ptr_twid_im[i]; + + ptr_in[2 * i + 1] = -ptr_in[2 * i] * ptr_twid_im[i] - ptr_in[2 * i + 1] * ptr_twid_re[i]; + ptr_in[2 * i] = temp; + } + return; +} + +VOID iusace_tcx_mdct(FLOAT32 *ptr_in, FLOAT32 *ptr_out, WORD32 length, + iusace_scratch_mem *pstr_scratch) { + FLOAT32 *ptr_pre_twid_re, *ptr_pre_twid_im; + FLOAT32 *ptr_post_twid_re, *ptr_post_twid_im; + WORD32 i; + FLOAT32 *ptr_real = pstr_scratch->p_temp_mdct; + WORD32 len_by_2 = length >> 1; + + iusace_get_pre_post_twid(&ptr_pre_twid_re, &ptr_pre_twid_im, &ptr_post_twid_re, + &ptr_post_twid_im, length); + + for (i = 0; i < len_by_2; i++) { + ptr_real[2 * i] = ptr_in[2 * i]; + ptr_real[2 * i + 1] = ptr_in[length - 1 - 2 * i]; + } + + /* pre twiddle */ + iusace_pre_twid(ptr_pre_twid_re, ptr_pre_twid_im, ptr_real, len_by_2); + + iusace_complex_fft(ptr_real, len_by_2, pstr_scratch); + + /* post twiddle */ + iusace_post_twid(ptr_post_twid_re, ptr_post_twid_im, ptr_real, len_by_2); + + for (i = 0; i < len_by_2; i++) { + ptr_out[2 * i] = ptr_real[2 * i]; + ptr_out[length - 1 - 2 * i] = ptr_real[2 * i + 1]; + } + + return; +} diff --git a/encoder/iusace_tcx_mdct.h b/encoder/iusace_tcx_mdct.h new file mode 100644 index 0000000..e28e47b --- /dev/null +++ b/encoder/iusace_tcx_mdct.h @@ -0,0 +1,29 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +VOID iusace_tcx_mdct_main(FLOAT32 *ptr_in, FLOAT32 *ptr_out, WORD32 l, WORD32 m, WORD32 r, + iusace_scratch_mem *pstr_scratch); + +VOID iusace_tcx_imdct(FLOAT32 *ptr_in, FLOAT32 *ptr_out, WORD32 l, WORD32 m, WORD32 r, + iusace_scratch_mem *pstr_scratch); + +VOID iusace_tcx_mdct(FLOAT32 *ptr_in, FLOAT32 *ptr_out, WORD32 length, + iusace_scratch_mem *pstr_scratch); diff --git a/encoder/iusace_tns_usac.c b/encoder/iusace_tns_usac.c new file mode 100644 index 0000000..cb62a4f --- /dev/null +++ b/encoder/iusace_tns_usac.c @@ -0,0 +1,533 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include +#include "ixheaace_mps_common_define.h" +#include "ixheaac_constants.h" +#include "iusace_cnst.h" +#include "ixheaac_type_def.h" +#include "iusace_bitbuffer.h" +#include "iusace_tns_usac.h" +#include "iusace_psy_mod.h" +#include "ixheaac_basic_ops32.h" +#include "ixheaac_basic_ops40.h" +#include "ixheaac_basic_ops.h" + +static const WORD32 iusace_tns_supported_sampling_rates[13] = { + 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 0}; + +static const UWORD16 iusace_tns_min_band_number_long[12] = {11, 12, 15, 16, 17, 20, + 25, 26, 24, 28, 30, 31}; + +static const UWORD16 iusace_tns_min_band_number_short[12] = {2, 2, 2, 3, 3, 4, + 6, 6, 8, 10, 10, 12}; + +static const WORD32 iusace_tns_max_bands_table[16][2] = {{31, 9}, /**< 96000 */ + {31, 9}, /**< 88200 */ + {34, 10}, /**< 64000 */ + {40, 14}, /**< 48000 */ + {42, 14}, /**< 44100 */ + {51, 14}, /**< 32000 */ + {47, 15}, /**< 24000 */ + {47, 15}, /**< 22050 */ + {43, 15}, /**< 16000 */ + {43, 15}, /**< 12000 */ + {43, 15}, /**< 11025 */ + {40, 15}, /**< 8000 */ + {40, 15}, /**< 7350 */ + {0, 0}, {0, 0}, {0, 0}}; + +static WORD32 iusace_freq_to_band_mapping(WORD32 freq, WORD32 sample_rate, WORD32 num_bands, + const WORD32 *ptr_band_start_offset) { + WORD32 line_num, band; + + line_num = (freq * ptr_band_start_offset[num_bands] * 4 / sample_rate + 1) / 2; + + if (line_num >= ptr_band_start_offset[num_bands]) { + return num_bands; + } + + for (band = 0; band < num_bands; band++) { + if (ptr_band_start_offset[band + 1] > line_num) break; + } + + if (line_num - ptr_band_start_offset[band] > ptr_band_start_offset[band + 1] - line_num) { + band++; + } + + return band; +}; + +static VOID iusace_calc_gauss_win(FLOAT64 *ptr_win, const WORD32 length, const WORD32 sample_rate, + const WORD32 win_seq, const FLOAT32 time_resolution) { + WORD32 i; + FLOAT32 gauss_exp = 3.14159265358979323f * sample_rate * 0.001f * (FLOAT32)time_resolution / + (win_seq != EIGHT_SHORT_SEQUENCE ? 1024.0f : 128.0f); + + gauss_exp = -0.5f * gauss_exp * gauss_exp; + + for (i = 0; i < length; i++) { + ptr_win[i] = (FLOAT32)exp(gauss_exp * (i + 0.5) * (i + 0.5)); + } + return; +} + +IA_ERRORCODE iusace_tns_init(WORD32 sampling_rate, WORD32 bit_rate, ia_tns_info *tns_info, + WORD32 num_channels) { + WORD32 fs_index = 0; + WORD32 lpc_stop_freq = 16000; + WORD32 lpc_start_freq_long = 2500, lpc_start_freq_short = 3750; + tns_info->threshold = 1.41f; + tns_info->tns_time_res_short = 0.6f; + tns_info->tns_time_res_long = 0.6f; + + if (sampling_rate == 14700) { + sampling_rate = 16000; + } + if (sampling_rate == 29400) { + sampling_rate = 32000; + } + + if (bit_rate < 32000) { + if (num_channels == 1) { + tns_info->threshold = 1.2f; + lpc_start_freq_long = 2000; + } + } else if (bit_rate < 36000) { + if (num_channels == 1) { + tns_info->tns_time_res_long = 0.8f; + } else { + tns_info->tns_time_res_long = 0.5f; + } + tns_info->tns_time_res_short = 0.3f; + } else { + tns_info->tns_time_res_long = 0.5f; + tns_info->tns_time_res_short = 0.3f; + } + + /** Determine if sampling rate is supported + */ + while (sampling_rate != iusace_tns_supported_sampling_rates[fs_index]) { + if (!iusace_tns_supported_sampling_rates[fs_index]) { + return -1; + } + fs_index++; + } + + tns_info->tns_max_bands_long = iusace_tns_max_bands_table[fs_index][0]; + tns_info->tns_max_bands_short = iusace_tns_max_bands_table[fs_index][1]; + tns_info->tns_max_order_long = 15; + tns_info->tns_max_order_short = 7; + + tns_info->tns_min_band_number_long = iusace_tns_min_band_number_long[fs_index]; + tns_info->tns_min_band_number_short = iusace_tns_min_band_number_short[fs_index]; + + tns_info->lpc_start_band_long = + iusace_freq_to_band_mapping(lpc_start_freq_long, sampling_rate, tns_info->max_sfb_long, + tns_info->sfb_offset_table_long); + + tns_info->lpc_start_band_short = + iusace_freq_to_band_mapping(lpc_start_freq_short, sampling_rate, tns_info->max_sfb_short, + tns_info->sfb_offset_table_short); + + tns_info->lpc_stop_band_long = iusace_freq_to_band_mapping( + lpc_stop_freq, sampling_rate, tns_info->max_sfb_long, tns_info->sfb_offset_table_long); + + tns_info->lpc_stop_band_short = iusace_freq_to_band_mapping( + lpc_stop_freq, sampling_rate, tns_info->max_sfb_short, tns_info->sfb_offset_table_short); + + iusace_calc_gauss_win(tns_info->win_long, tns_info->tns_max_order_long + 1, sampling_rate, + ONLY_LONG_SEQUENCE, tns_info->tns_time_res_long); + + iusace_calc_gauss_win(tns_info->win_short, tns_info->tns_max_order_short + 1, sampling_rate, + EIGHT_SHORT_SEQUENCE, tns_info->tns_time_res_short); + return 0; +} + +VOID iusace_tns_filter(WORD32 length, FLOAT64 *spec, ia_tns_filter_data *filter, + FLOAT64 *scratch_tns_filter) { + WORD32 i, j, k = 0; + WORD32 order = filter->order; + FLOAT64 *a = filter->a_coeffs; + FLOAT64 *temp = scratch_tns_filter; + + /** Determine loop parameters for given direction + */ + if (filter->direction) { + /** Startup, initial state is zero + */ + temp[length - 1] = spec[length - 1]; + for (i = length - 2; i > (length - 1 - order); i--) { + temp[i] = spec[i]; + k++; + for (j = 1; j <= k; j++) { + spec[i] += temp[i + j] * a[j]; + } + } + + /** Now filter the rest + */ + for (i = length - 1 - order; i >= 0; i--) { + temp[i] = spec[i]; + for (j = 1; j <= order; j++) { + spec[i] += temp[i + j] * a[j]; + } + } + } else { + /** Startup, initial state is zero + */ + temp[0] = spec[0]; + for (i = 1; i < order; i++) { + temp[i] = spec[i]; + for (j = 1; j <= i; j++) { + spec[i] += temp[i - j] * a[j]; + } + } + + /** Now filter the rest + */ + for (i = order; i < length; i++) { + temp[i] = spec[i]; + for (j = 1; j <= order; j++) { + spec[i] += temp[i - j] * a[j]; + } + } + } + + return; +} + +static WORD32 iusace_truncate_coeffs(WORD32 f_order, FLOAT64 threshold, FLOAT64 *k_array) { + WORD32 i; + for (i = f_order; i >= 0; i--) { + k_array[i] = (fabs(k_array[i]) > threshold) ? k_array[i] : 0.0; + if (k_array[i] != 0.0) { + return i; + } + } + return 0; +} + +VOID iusace_quantize_reflection_coeffs(WORD32 f_order, WORD32 coeff_res, FLOAT64 *k_array, + WORD32 *index_array) { + FLOAT64 iqfac, iqfac_m; + WORD32 i; + + iqfac = (((SIZE_T)1 << (coeff_res - 1)) - 0.5) / (PI / 2); + iqfac_m = (((SIZE_T)1 << (coeff_res - 1)) + 0.5) / (PI / 2); + + /* Quantize and inverse quantize */ + for (i = 1; i <= f_order; i++) { + index_array[i] = (WORD32)(0.5 + (asin(k_array[i]) * ((k_array[i] >= 0) ? iqfac : iqfac_m))); + k_array[i] = sin((FLOAT64)index_array[i] / ((index_array[i] >= 0) ? iqfac : iqfac_m)); + } + return; +} + +VOID iusace_tns_auto_corr(WORD32 max_order, WORD32 data_size, FLOAT64 *data, FLOAT64 *r_array) { + WORD32 i, j; + FLOAT64 tmp_var; + for (i = 0; i < data_size; i += 2) { + const FLOAT64 *input1 = &data[i]; + FLOAT64 temp1 = *input1; + FLOAT64 temp2 = *(input1 + 1); + FLOAT64 inp_tmp1 = *input1++; + for (j = 0; j <= max_order; j++) { + FLOAT64 inp_tmp2; + tmp_var = temp1 * inp_tmp1; + inp_tmp2 = *input1++; + tmp_var += temp2 * inp_tmp2; + r_array[j] += tmp_var; + j++; + tmp_var = temp1 * inp_tmp2; + inp_tmp1 = *input1++; + tmp_var += temp2 * inp_tmp1; + r_array[j] += tmp_var; + } + } + return; +} + +static FLOAT64 iusace_levinson_durbin(WORD32 order, WORD32 data_size, FLOAT64 *ptr_data, + FLOAT64 *ptr_k, FLOAT64 *ptr_win, FLOAT64 *ptr_scratch) { + WORD32 i, j; + FLOAT64 *ptr_work_buffer_temp; + FLOAT64 *ptr_work_buffer = ptr_scratch; + FLOAT64 *ptr_input = ptr_scratch + TNS_MAX_ORDER + 1; + memset(ptr_input, 0, (TNS_MAX_ORDER + 1) * sizeof(ptr_input[0])); + iusace_tns_auto_corr(order, data_size, ptr_data, ptr_input); + + WORD32 num_of_coeff = order; + FLOAT64 *ptr_refl_coeff = ptr_k; + ptr_k[0] = 1.0; + + if (ptr_input[0] == 0) { + return 0; + } + + for (i = 0; i < num_of_coeff + 1; i++) { + ptr_input[i] = ptr_input[i] * ptr_win[i]; + } + + FLOAT64 tmp_var; + ptr_work_buffer[0] = ptr_input[0]; + + for (i = 1; i < num_of_coeff; i++) { + tmp_var = ptr_input[i]; + ptr_work_buffer[i] = tmp_var; + ptr_work_buffer[i + num_of_coeff - 1] = tmp_var; + } + ptr_work_buffer[i + num_of_coeff - 1] = ptr_input[i]; + + for (i = 0; i < num_of_coeff; i++) { + FLOAT64 refc, tmp; + tmp = ptr_work_buffer[num_of_coeff + i]; + if (tmp < 0) { + tmp = -tmp; + } else { + if (ptr_work_buffer[0] < tmp) { + break; + } + } + if (ptr_work_buffer[0] == 0) { + refc = 0; + } else { + refc = tmp / ptr_work_buffer[0]; + } + + if (ptr_work_buffer[num_of_coeff + i] > 0) { + refc = -refc; + } + ptr_refl_coeff[i + 1] = refc; + ptr_work_buffer_temp = &(ptr_work_buffer[num_of_coeff]); + + for (j = i; j < num_of_coeff; j++) { + FLOAT64 accu1, accu2; + accu1 = refc * ptr_work_buffer[j - i]; + accu1 += ptr_work_buffer_temp[j]; + accu2 = refc * ptr_work_buffer_temp[j]; + accu2 += ptr_work_buffer[j - i]; + ptr_work_buffer_temp[j] = accu1; + ptr_work_buffer[j - i] = accu2; + } + } + return (ptr_input[0] / ptr_work_buffer[0]); +} + +static VOID iusace_step_up(WORD32 f_order, FLOAT64 *ptr_k, FLOAT64 *ptr_a, FLOAT64 *ptr_scratch) { + FLOAT64 *ptr_a_temp = ptr_scratch; + WORD32 i, order; + + ptr_a[0] = 1.0; + ptr_a_temp[0] = 1.0; + for (order = 1; order <= f_order; order++) { + ptr_a[order] = 0.0; + for (i = 1; i <= order; i++) { + ptr_a_temp[i] = ptr_a[i] + ptr_k[order] * ptr_a[order - i]; + } + for (i = 1; i <= order; i++) { + ptr_a[i] = ptr_a_temp[i]; + } + } + return; +} + +static VOID iusace_calc_weighted_spec(FLOAT64 *ptr_spec, FLOAT64 *ptr_wgt_spec, + FLOAT32 *ptr_sfb_en, WORD32 *ptr_sfb_offset, + WORD32 lpc_start_band, WORD32 lpc_stop_band, + FLOAT64 *ptr_scratch) { + WORD32 i, sfb; + FLOAT32 temp; + FLOAT32 *ptr_tns_sfb_mean = (FLOAT32 *)ptr_scratch; + memset(ptr_scratch, 0, MAX_NUM_GROUPED_SFB * sizeof(ptr_tns_sfb_mean[0])); + WORD32 lpc_stop_line = ptr_sfb_offset[lpc_stop_band]; + WORD32 lpc_start_line = ptr_sfb_offset[lpc_start_band]; + + for (sfb = lpc_start_band; sfb < lpc_stop_band; sfb++) { + ptr_tns_sfb_mean[sfb] = (FLOAT32)(1.0 / sqrt(ptr_sfb_en[sfb] + 1e-30f)); + } + + sfb = lpc_start_band; + temp = ptr_tns_sfb_mean[sfb]; + + for (i = lpc_start_line; i < lpc_stop_line; i++) { + if (ptr_sfb_offset[sfb + 1] == i) { + sfb++; + + if (sfb + 1 < lpc_stop_band) { + temp = ptr_tns_sfb_mean[sfb]; + } + } + ptr_wgt_spec[i] = temp; + } + + for (i = lpc_stop_line - 2; i >= lpc_start_line; i--) { + ptr_wgt_spec[i] = (ptr_wgt_spec[i] + ptr_wgt_spec[i + 1]) * 0.5f; + } + + for (i = lpc_start_line + 1; i < lpc_stop_line; i++) { + ptr_wgt_spec[i] = (ptr_wgt_spec[i] + ptr_wgt_spec[i - 1]) * 0.5f; + } + + for (i = lpc_start_line; i < lpc_stop_line; i++) { + ptr_wgt_spec[i] = ptr_wgt_spec[i] * ptr_spec[i]; + } + return; +} + +VOID iusace_tns_data_sync(ia_tns_info *ptr_tns_dest, ia_tns_info *ptr_tns_src, const WORD32 w, + WORD32 order) { + ia_tns_window_data *win_data_src = &ptr_tns_src->window_data[w]; + ia_tns_window_data *win_data_dest = &ptr_tns_dest->window_data[w]; + WORD32 i; + if (fabs(win_data_dest->tns_pred_gain - win_data_src->tns_pred_gain) < + ((FLOAT32)0.03f * win_data_dest->tns_pred_gain)) { + win_data_dest->tns_active = win_data_src->tns_active; + + for (i = 0; i < order; i++) { + win_data_dest->tns_filter->k_coeffs[i] = win_data_src->tns_filter->k_coeffs[i]; + } + } + return; +} + +VOID iusace_tns_encode(ia_tns_info *pstr_tns_info_ch2, ia_tns_info *pstr_tns_info, + FLOAT32 *ptr_sfb_energy, WORD32 w, WORD32 i_ch, WORD32 low_pass_line, + FLOAT64 *ptr_scratch_tns_filter, WORD32 core_mode, + FLOAT64 *ptr_tns_scratch) { + WORD32 number_of_bands = pstr_tns_info->number_of_bands; + WORD32 block_type = pstr_tns_info->block_type; + FLOAT64 *ptr_spec = pstr_tns_info->spec; + WORD32 start_band, stop_band, order; /**< bands over which to apply TNS */ + WORD32 length_in_bands; /**< Length to filter, in bands */ + WORD32 start_index, length; + WORD32 nbands; + WORD32 coeff_res; + FLOAT64 *ptr_weighted_spec = ptr_tns_scratch; + memset(ptr_weighted_spec, 0, 4096 * sizeof(ptr_weighted_spec[0])); + FLOAT64 *ptr_scratch = ptr_tns_scratch + 4096; + FLOAT64 *ptr_window = NULL; + WORD32 lpc_start_band, lpc_stop_band; + WORD32 *ptr_sfb_offset_table; + + switch (block_type) { + case EIGHT_SHORT_SEQUENCE: + start_band = pstr_tns_info->tns_min_band_number_short; + stop_band = number_of_bands; + length_in_bands = stop_band - start_band; + order = pstr_tns_info->tns_max_order_short; + start_band = MIN(start_band, pstr_tns_info->tns_max_bands_short); + stop_band = MIN(stop_band, pstr_tns_info->tns_max_bands_short); + coeff_res = 3; + ptr_window = pstr_tns_info->win_short; + nbands = pstr_tns_info->max_sfb_short; + lpc_start_band = pstr_tns_info->lpc_start_band_short; + lpc_stop_band = pstr_tns_info->lpc_stop_band_short; + if (core_mode == CORE_MODE_FD) { + ptr_sfb_offset_table = pstr_tns_info->sfb_offset_table_short; + } else { + ptr_sfb_offset_table = pstr_tns_info->sfb_offset_table_short_tcx; + } + break; + + default: + start_band = pstr_tns_info->tns_min_band_number_long; + stop_band = number_of_bands; + length_in_bands = stop_band - start_band; + order = pstr_tns_info->tns_max_order_long; + start_band = MIN(start_band, pstr_tns_info->tns_max_bands_long); + stop_band = MIN(stop_band, pstr_tns_info->tns_max_bands_long); + coeff_res = 4; + ptr_window = pstr_tns_info->win_long; + nbands = pstr_tns_info->max_sfb_long; + lpc_start_band = pstr_tns_info->lpc_start_band_long; + lpc_stop_band = pstr_tns_info->lpc_stop_band_long; + ptr_sfb_offset_table = pstr_tns_info->sfb_offset_table_long; + break; + } + + /** Make sure that start and stop bands < max_sfb + * Make sure that start and stop bands >= 0 + */ + start_band = MIN(start_band, nbands); + stop_band = MIN(stop_band, nbands); + start_band = MAX(start_band, 0); + stop_band = MAX(stop_band, 0); + + pstr_tns_info->tns_data_present = 0; /**< default TNS not used */ + + /** Perform analysis and filtering for each window + */ + { + ia_tns_window_data *window_data = &pstr_tns_info->window_data[w]; + ia_tns_filter_data *tns_filter = window_data->tns_filter; + FLOAT64 *k = tns_filter->k_coeffs; /**< reflection coeffs */ + FLOAT64 *a = tns_filter->a_coeffs; /**< prediction coeffs */ + + iusace_calc_weighted_spec(ptr_spec, ptr_weighted_spec, ptr_sfb_energy, ptr_sfb_offset_table, + lpc_start_band, lpc_stop_band, ptr_scratch); + + window_data->n_filt = 0; + window_data->coef_res = coeff_res; + + start_index = ptr_sfb_offset_table[lpc_start_band]; + length = + ptr_sfb_offset_table[lpc_stop_band] - + ptr_sfb_offset_table[lpc_start_band]; /**< The length of the spectral data to be + processed + */ + + window_data->tns_pred_gain = iusace_levinson_durbin( + order, length, &ptr_weighted_spec[start_index], k, ptr_window, ptr_scratch); + + window_data->tns_active = 0; + if (window_data->tns_pred_gain > DEF_TNS_GAIN_THRESH) { + window_data->tns_active = 1; + } + + if (i_ch == 1) { + iusace_tns_data_sync(pstr_tns_info, pstr_tns_info_ch2, w, order); + } + + if (window_data->tns_pred_gain > DEF_TNS_GAIN_THRESH) { + /** Use TNS + */ + WORD32 truncated_order; + window_data->n_filt++; + pstr_tns_info->tns_data_present = 1; + tns_filter->direction = 0; + tns_filter->coef_compress = 0; + tns_filter->length = length_in_bands; + iusace_quantize_reflection_coeffs(order, coeff_res, k, tns_filter->index); + truncated_order = iusace_truncate_coeffs(order, DEF_TNS_COEFF_THRESH, k); + tns_filter->order = truncated_order; + iusace_step_up(truncated_order, k, a, ptr_scratch); /**< Compute prediction coefficients */ + start_index = ptr_sfb_offset_table[start_band]; + length = MIN(ptr_sfb_offset_table[stop_band], low_pass_line) - start_index; + if (block_type == EIGHT_SHORT_SEQUENCE) { + length = ptr_sfb_offset_table[stop_band] - start_index; + } + iusace_tns_filter(length, &ptr_spec[start_index], tns_filter, + ptr_scratch_tns_filter); /**< filter */ + } + } + return; +} diff --git a/encoder/iusace_tns_usac.h b/encoder/iusace_tns_usac.h new file mode 100644 index 0000000..414d6ac --- /dev/null +++ b/encoder/iusace_tns_usac.h @@ -0,0 +1,88 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +#define LN (2048) +#define SN (256) +#define LN2 (LN / 2) +#define NSHORT (LN / SN) + +#define TNS_MAX_ORDER 31 +#define DEF_TNS_GAIN_THRESH 1.41 +#define DEF_TNS_COEFF_THRESH 0.1 +#define DEF_TNS_RES_OFFSET 3 + +#ifndef PI +#define PI 3.14159265358979323846 +#endif + +typedef struct { + WORD32 order; /**< Filter order */ + WORD32 direction; /**< Filtering direction */ + WORD32 coef_compress; /**< Are coeffs compressed? */ + WORD32 length; /**< Length, in bands */ + FLOAT64 a_coeffs[TNS_MAX_ORDER + 1]; /**< AR Coefficients */ + FLOAT64 k_coeffs[TNS_MAX_ORDER + 1]; /**< Reflection Coefficients */ + WORD32 index[TNS_MAX_ORDER + 1]; /**< Coefficient indices */ +} ia_tns_filter_data; + +typedef struct { + WORD32 n_filt; /**< number of filters */ + WORD32 coef_res; /**< Coefficient resolution */ + ia_tns_filter_data tns_filter[3]; /**< TNS filters */ + FLOAT64 tns_pred_gain; + WORD32 tns_active; +} ia_tns_window_data; + +typedef struct { + WORD32 tns_data_present; + WORD32 tns_min_band_number_long; + WORD32 tns_min_band_number_short; + WORD32 tns_max_bands_long; + WORD32 tns_max_bands_short; + WORD32 tns_max_order_long; + WORD32 tns_max_order_short; + WORD32 lpc_start_band_long; + WORD32 lpc_start_band_short; + WORD32 lpc_stop_band_long; + WORD32 lpc_stop_band_short; + ia_tns_window_data window_data[NSHORT]; /**< TNS data per window */ + WORD32 *sfb_offset_table_short; /**< Scalefactor band offset table */ + WORD32 *sfb_offset_table_short_tcx; /**< Scalefactor band offset table */ + WORD32 *sfb_offset_table_long; /**< Scalefactor band offset table */ + WORD32 max_sfb_short; /**< max_sfb */ + WORD32 max_sfb_long; /**< max_sfb */ + FLOAT32 threshold; + FLOAT32 tns_time_res_short; + FLOAT32 tns_time_res_long; + FLOAT64 win_short[8]; + FLOAT64 win_long[16]; + WORD32 block_type; /**< block type */ + WORD32 number_of_bands; /**< number of bands per window */ + FLOAT64 *spec; /**< Spectral data array */ +} ia_tns_info; + +IA_ERRORCODE iusace_tns_init(WORD32 sampling_rate, WORD32 bit_rate, ia_tns_info *pstr_tns_info, + WORD32 num_channels); + +VOID iusace_tns_encode(ia_tns_info *pstr_tns_info_ch2, ia_tns_info *pstr_tns_info, + FLOAT32 *ptr_sfb_energy, WORD32 w, WORD32 i_ch, WORD32 low_pass_line, + FLOAT64 *ptr_scratch_tns_filter, WORD32 core_mode, + FLOAT64 *ptr_tns_scratch); diff --git a/encoder/iusace_windowing.c b/encoder/iusace_windowing.c new file mode 100644 index 0000000..4bed683 --- /dev/null +++ b/encoder/iusace_windowing.c @@ -0,0 +1,180 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include + +#include "ixheaac_type_def.h" +#include "iusace_cnst.h" +#include "iusace_block_switch_const.h" +#include "iusace_rom.h" + +IA_ERRORCODE iusace_calc_window(FLOAT64 **win, WORD32 win_sz, WORD32 win_sel) { + switch (win_sel) { + case WIN_SEL_0: + switch (win_sz) { + case WIN_LEN_96: + *win = (FLOAT64 *)iexheaac_sine_win_96; + break; + case WIN_LEN_192: + *win = (FLOAT64 *)iexheaac_sine_win_192; + break; + case WIN_LEN_128: + *win = (FLOAT64 *)iusace_sine_win_128; + break; + case WIN_LEN_256: + *win = (FLOAT64 *)iusace_sine_win_256; + break; + case WIN_LEN_768: + *win = (FLOAT64 *)iexheaac_sine_win_768; + break; + case WIN_LEN_1024: + *win = (FLOAT64 *)iusace_sine_win_1024; + break; + default: + return -1; + break; + } + break; + case WIN_SEL_1: + switch (win_sz) { + case WIN_LEN_96: + *win = (FLOAT64 *)iexheaac_kbd_win_96; + break; + case WIN_LEN_128: + *win = (FLOAT64 *)iusace_sine_win_128; + break; + case WIN_LEN_192: + *win = (FLOAT64 *)iexheaac_kbd_win_192; + break; + case WIN_LEN_256: + *win = (FLOAT64 *)iusace_kbd_win256; + break; + case WIN_LEN_768: + *win = (FLOAT64 *)iexheaac_kbd_win_768; + break; + case WIN_LEN_1024: + *win = (FLOAT64 *)iusace_kbd_win1024; + break; + default: + return -1; + break; + } + break; + + default: + return -1; + break; + } + return 0; +} + +VOID iusace_windowing_long(FLOAT64 *ptr_overlap, FLOAT64 *ptr_win_long, FLOAT64 *ptr_win_buf, + FLOAT64 *ptr_in_data, WORD32 n_long) { + WORD32 i; + FLOAT64 *ptr_win = ptr_win_long + n_long - 1; + WORD32 data_size = (OVERLAP_WIN_SIZE_576 * n_long) / LEN_SUPERFRAME; + + for (i = 0; i < n_long; i++) { + ptr_win_buf[i] = ptr_overlap[i] * ptr_win_long[i]; + } + + memcpy(ptr_overlap, ptr_overlap + n_long, data_size * sizeof(ptr_overlap[0])); + memcpy(ptr_overlap + data_size, ptr_in_data, n_long * sizeof(ptr_overlap[0])); + + for (i = 0; i < n_long; i++) { + ptr_win_buf[i + n_long] = ptr_overlap[i] * (*ptr_win--); + } + + return; +} + +VOID iusace_windowing_long_start(FLOAT64 *ptr_overlap, FLOAT64 *ptr_win_long, + FLOAT64 *ptr_win_buf, FLOAT64 *ptr_in_data, WORD32 n_long, + WORD32 nflat_ls, FLOAT64 *ptr_win_med, WORD32 win_sz) { + WORD32 i; + FLOAT64 *ptr_win = ptr_win_buf + 2 * n_long - 1; + WORD32 data_size = (OVERLAP_WIN_SIZE_576 * n_long) / LEN_SUPERFRAME; + + for (i = 0; i < n_long; i++) { + ptr_win_buf[i] = ptr_overlap[i] * ptr_win_long[i]; + } + + memcpy(ptr_overlap, ptr_overlap + n_long, data_size * sizeof(ptr_overlap[0])); + memcpy(ptr_overlap + data_size, ptr_in_data, n_long * sizeof(ptr_overlap[0])); + memcpy(ptr_win_buf + n_long, ptr_overlap, nflat_ls * sizeof(ptr_win_buf[0])); + + ptr_win_med = ptr_win_med + win_sz - 1; + win_sz = n_long - 2 * nflat_ls; + + for (i = 0; i < win_sz; i++) { + ptr_win_buf[i + n_long + nflat_ls] = ptr_overlap[i + nflat_ls] * (*ptr_win_med--); + } + + for (i = 0; i < nflat_ls; i++) { + *ptr_win-- = 0; + } + + return; +} + +VOID iusace_windowing_long_stop(FLOAT64 *ptr_overlap, FLOAT64 *ptr_win_long, FLOAT64 *ptr_win_buf, + FLOAT64 *ptr_in_data, WORD32 n_long, WORD32 nflat_ls, + FLOAT64 *ptr_win_med, WORD32 win_sz) { + WORD32 i; + FLOAT64 *ptr_win = ptr_win_long + n_long - 1; + WORD32 data_size = (OVERLAP_WIN_SIZE_576 * n_long) / LEN_SUPERFRAME; + + memset(ptr_win_buf, 0, nflat_ls * sizeof(FLOAT64)); + for (i = 0; i < win_sz; i++) { + ptr_win_buf[i + nflat_ls] = ptr_overlap[i + nflat_ls] * ptr_win_med[i]; + } + + memcpy(ptr_win_buf + nflat_ls + win_sz, ptr_overlap + nflat_ls + win_sz, + nflat_ls * sizeof(ptr_win_buf[0])); + memcpy(ptr_overlap, ptr_overlap + n_long, data_size * sizeof(ptr_overlap[0])); + memcpy(ptr_overlap + data_size, ptr_in_data, n_long * sizeof(ptr_overlap[0])); + + for (i = 0; i < n_long; i++) { + ptr_win_buf[i + n_long] = ptr_overlap[i] * (*ptr_win--); + } + return; +} + +VOID iusace_windowing_stop_start(FLOAT64 *ptr_overlap, FLOAT64 *ptr_win_buf, FLOAT64 *ptr_win_med, + WORD32 win_sz, WORD32 n_long) { + WORD32 i; + FLOAT64 *win_gen; + WORD32 wsize = (n_long - win_sz) >> 1; + win_gen = ptr_win_med; + + for (i = 0; i < win_sz; i++) { + ptr_win_buf[wsize + i] = ptr_overlap[wsize + i] * (*win_gen++); + } + memcpy(ptr_win_buf + wsize, ptr_overlap + wsize, wsize * sizeof(FLOAT64)); + memcpy(ptr_win_buf + n_long, ptr_overlap + n_long, wsize * sizeof(FLOAT64)); + + win_gen = ptr_win_med + win_sz - 1; + win_sz = n_long - 2 * wsize; + + for (i = 0; i < win_sz; i++) { + ptr_win_buf[n_long + wsize + i] = ptr_overlap[n_long + wsize + i] * (*win_gen--); + } + return; +} diff --git a/encoder/iusace_windowing.h b/encoder/iusace_windowing.h new file mode 100644 index 0000000..7142674 --- /dev/null +++ b/encoder/iusace_windowing.h @@ -0,0 +1,34 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +IA_ERRORCODE iusace_calc_window(FLOAT64 **win, WORD32 win_sz, WORD32 win_sel); +VOID iusace_windowing_long(FLOAT64 *ptr_out_buf, FLOAT64 *ptr_win_long, FLOAT64 *ptr_win_buf, + FLOAT64 *ptr_in_data, WORD32 n_long); +VOID iusace_windowing_long_start(FLOAT64 *ptr_out_buf, FLOAT64 *ptr_win_long, + FLOAT64 *ptr_win_buf, FLOAT64 *ptr_in_data, WORD32 n_long, + WORD32 nflat_ls, FLOAT64 *ptr_win_med, WORD32 win_sz); +VOID iusace_windowing_long_stop(FLOAT64 *ptr_out_buf, FLOAT64 *ptr_win_long, FLOAT64 *ptr_win_buf, + FLOAT64 *ptr_in_data, WORD32 n_long, WORD32 nflat_ls, + FLOAT64 *ptr_win_med, WORD32 win_sz); +VOID iusace_windowing_stop_start(FLOAT64 *ptr_out_buf, FLOAT64 *ptr_win_buf, FLOAT64 *ptr_win_med, + WORD32 win_sz, WORD32 n_long); +WORD32 iusace_fd_mdct(ia_usac_data_struct *pstr_usac_data, + ia_usac_encoder_config_struct *pstr_usac_config, WORD32 ch_idx); diff --git a/encoder/iusace_write_bitstream.c b/encoder/iusace_write_bitstream.c new file mode 100644 index 0000000..07163c5 --- /dev/null +++ b/encoder/iusace_write_bitstream.c @@ -0,0 +1,740 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include +#include "ixheaac_type_def.h" +#include "iusace_bitbuffer.h" + +/* DRC */ +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" +#include "impd_drc_uni_drc_eq.h" +#include "impd_drc_uni_drc_filter_bank.h" +#include "impd_drc_gain_enc.h" +#include "impd_drc_struct_def.h" + +#include "ixheaace_mps_common_define.h" +#include "iusace_cnst.h" +#include "iusace_tns_usac.h" +#include "iusace_psy_mod.h" +#include "iusace_tns_usac.h" +#include "iusace_config.h" +#include "iusace_arith_enc.h" +#include "ixheaace_adjust_threshold_data.h" +#include "iusace_block_switch_const.h" +#include "iusace_block_switch_struct_def.h" +#include "iusace_fd_qc_util.h" +#include "iusace_fd_quant.h" +#include "iusace_ms.h" +#include "iusace_signal_classifier.h" +#include "ixheaace_sbr_header.h" +#include "ixheaace_config.h" +#include "ixheaace_asc_write.h" +#include "iusace_main.h" +#include "iusace_rom.h" + +#if DEBUG_DUMP +extern FILE *out_file; +#endif + +WORD32 iusace_write_scf_data(ia_bit_buf_struct *it_bit_buf, WORD32 max_sfb, WORD32 num_sfb, + const WORD32 *ptr_scale_factors, WORD32 num_win_grps, + WORD32 global_gain, const WORD32 huff_tab[CODE_BOOK_ALPHA_LAV][2]) { + WORD32 write_flag = (it_bit_buf != NULL); + WORD32 i, j, bit_count = 0; + WORD32 diff, length, codeword; + WORD32 index = 0; + WORD32 sf_out = 0; + WORD32 sf_not_out = 0; + WORD32 previous_scale_factor = global_gain; + + for (j = 0; j < num_win_grps; j++) { + for (i = 0; i < max_sfb; i++) { + if (!((i == 0) && (j == 0))) { + diff = ptr_scale_factors[index] - previous_scale_factor; + length = huff_tab[diff + 60][0]; + bit_count += length; + previous_scale_factor = ptr_scale_factors[index]; + if (write_flag == 1) { + codeword = huff_tab[diff + 60][1]; + iusace_write_bits_buf(it_bit_buf, codeword, (UWORD8)length); + sf_out++; + } + } + index++; + } + for (; i < num_sfb; i++) { + sf_not_out++; + index++; + } + } + + return (bit_count); +} + +WORD32 iusace_write_ms_data(ia_bit_buf_struct *it_bit_buf, WORD32 ms_mask, + WORD32 ms_used[MAX_SHORT_WINDOWS][MAX_SFB_LONG], WORD32 num_win_grps, + WORD32 nr_of_sfb) { + WORD32 write_flag = (it_bit_buf != NULL); + WORD32 bit_count = 0; + WORD32 i, j; + WORD32 ms_mask_write = ms_mask; + + if (write_flag) iusace_write_bits_buf(it_bit_buf, ms_mask_write, 2); + bit_count += 2; + + if (ms_mask_write == 1) { + for (i = 0; i < num_win_grps; i++) { + for (j = 0; j < nr_of_sfb; j++) { + if (write_flag) iusace_write_bits_buf(it_bit_buf, ms_used[i][j], 1); + bit_count += 1; + } + } + } + + return bit_count; +} + +WORD32 iusace_write_tns_data(ia_bit_buf_struct *it_bit_buf, ia_tns_info *pstr_tns_info, + WORD32 window_sequence, WORD32 core_mode) { + WORD32 write_flag = (it_bit_buf != NULL); + WORD32 bit_count = 0; + WORD32 num_windows; + WORD32 len_tns_nfilt; + WORD32 len_tns_length; + WORD32 len_tns_order; + WORD32 filt; + WORD32 res_bits; + UWORD32 coeff; + WORD32 w; + + if (window_sequence == EIGHT_SHORT_SEQUENCE) { + num_windows = MAX_SHORT_WINDOWS; + len_tns_nfilt = 1; + len_tns_length = 4; + len_tns_order = 3; + } else { + num_windows = 1; + len_tns_nfilt = 2; + len_tns_length = 6; + len_tns_order = 4; + } + if (core_mode == 1) { + num_windows = 1; + } + + for (w = 0; w < num_windows; w++) { + ia_tns_window_data *ptr_win_data = &pstr_tns_info->window_data[w]; + WORD32 n_filt = ptr_win_data->n_filt; + if (write_flag) { + iusace_write_bits_buf(it_bit_buf, n_filt, (UWORD8)len_tns_nfilt); + } + bit_count += len_tns_nfilt; + if (n_filt) { + res_bits = ptr_win_data->coef_res; + if (write_flag) { + iusace_write_bits_buf(it_bit_buf, res_bits - DEF_TNS_RES_OFFSET, 1); + } + bit_count += 1; + for (filt = 0; filt < n_filt; filt++) { + ia_tns_filter_data *ptr_tns_filt = &ptr_win_data->tns_filter[filt]; + WORD32 order = ptr_tns_filt->order; + if (write_flag) { + iusace_write_bits_buf(it_bit_buf, ptr_tns_filt->length, (UWORD8)len_tns_length); + iusace_write_bits_buf(it_bit_buf, order, (UWORD8)len_tns_order); + } + bit_count += (len_tns_length + len_tns_order); + if (order) { + WORD32 i; + if (write_flag) { + iusace_write_bits_buf(it_bit_buf, ptr_tns_filt->direction, 1); + iusace_write_bits_buf(it_bit_buf, ptr_tns_filt->coef_compress, 1); + } + bit_count += 2; + for (i = 1; i <= order; i++) { + if (write_flag) { + coeff = (UWORD32)(ptr_tns_filt->index[i]) & ((1 << res_bits) - 1); + iusace_write_bits_buf(it_bit_buf, coeff, (UWORD8)res_bits); + } + bit_count += res_bits; + } + } + } + } + } + + return bit_count; +} + +static WORD32 iusace_calc_grouping_bits(const WORD32 *ptr_win_grp_len, WORD32 num_win_grps) { + WORD32 grouping_bits = 0; + WORD32 tmp[8] = {0}; + WORD32 i, j; + WORD32 index = 0; + + for (i = 0; i < num_win_grps; i++) { + for (j = 0; j < ptr_win_grp_len[i]; j++) { + tmp[index++] = i; + } + } + + for (i = 1; i < 8; i++) { + grouping_bits = grouping_bits << 1; + if (tmp[i] == tmp[i - 1]) { + grouping_bits++; + } + } + + return (grouping_bits); +} + +WORD32 iusace_write_ics_info(ia_bit_buf_struct *it_bit_buf, ia_sfb_params_struct *pstr_sfb_prms, + WORD32 ch) { + WORD32 write_flag = (it_bit_buf != NULL); + WORD32 bit_count = 0; + WORD32 win_seq = 0; + WORD32 grouping_bits = 0; + WORD32 max_sfb = pstr_sfb_prms->max_sfb[ch]; + WORD32 window_sequence = pstr_sfb_prms->window_sequence[ch]; + WORD32 window_shape = pstr_sfb_prms->window_shape[ch]; + WORD32 num_win_grps = pstr_sfb_prms->num_window_groups[ch]; + + switch (window_sequence) { + case EIGHT_SHORT_SEQUENCE: + win_seq = 2; + break; + case ONLY_LONG_SEQUENCE: + win_seq = 0; + break; + case LONG_START_SEQUENCE: + case STOP_START_SEQUENCE: + win_seq = 1; + break; + case LONG_STOP_SEQUENCE: + win_seq = 3; + break; + default: + win_seq = 3; + break; + } + if (write_flag) iusace_write_bits_buf(it_bit_buf, win_seq, 2); + bit_count += 2; + + if (write_flag) iusace_write_bits_buf(it_bit_buf, window_shape, 1); + bit_count += 1; + + if (window_sequence == EIGHT_SHORT_SEQUENCE) { + if (write_flag) iusace_write_bits_buf(it_bit_buf, max_sfb, 4); + bit_count += 4; + + grouping_bits = + iusace_calc_grouping_bits(pstr_sfb_prms->window_group_length[ch], num_win_grps); + if (write_flag) iusace_write_bits_buf(it_bit_buf, grouping_bits, 7); + bit_count += 7; + } else { + if (write_flag) iusace_write_bits_buf(it_bit_buf, max_sfb, 6); + bit_count += 6; + } + + return (bit_count); +} + +WORD32 iusace_write_cplx_pred_data(ia_bit_buf_struct *it_bit_buf, WORD32 num_win_grps, + WORD32 num_sfb, WORD32 complex_coef, + WORD32 pred_coeffs_re[MAX_SHORT_WINDOWS][MAX_SFB_LONG], + WORD32 pred_coeffs_im[MAX_SHORT_WINDOWS][MAX_SFB_LONG], + const WORD32 huff_tab[CODE_BOOK_ALPHA_LAV][2], + WORD32 const usac_independency_flg, WORD32 pred_dir, + WORD32 cplx_pred_used[MAX_SHORT_WINDOWS][MAX_SFB_LONG], + WORD32 cplx_pred_all, WORD32 *ptr_prev_alpha_coeff_re, + WORD32 *ptr_prev_alpha_coeff_im, WORD32 *delta_code_time) { + WORD32 write_flag = (it_bit_buf != NULL); + WORD32 bit_count = 0; + WORD32 i, j; + WORD32 g; + WORD32 sfb; + const WORD32 sfb_per_pred_band = 2; + WORD32 length_temp1_re[MAX_SHORT_WINDOWS][MAX_SFB_LONG], + length_temp2_re[MAX_SHORT_WINDOWS][MAX_SFB_LONG], + length_temp1_im[MAX_SHORT_WINDOWS][MAX_SFB_LONG], + length_temp2_im[MAX_SHORT_WINDOWS][MAX_SFB_LONG]; + WORD32 code_word_temp1_re[MAX_SHORT_WINDOWS][MAX_SFB_LONG], + code_word_temp2_re[MAX_SHORT_WINDOWS][MAX_SFB_LONG], + code_word_temp1_im[MAX_SHORT_WINDOWS][MAX_SFB_LONG], + code_word_temp2_im[MAX_SHORT_WINDOWS][MAX_SFB_LONG]; + WORD32 length_tot1 = 0, length_tot2 = 0; + + if (write_flag) iusace_write_bits_buf(it_bit_buf, cplx_pred_all, 1); + bit_count += 1; + + if (cplx_pred_all == 0) { + for (g = 0; g < num_win_grps; g++) { + for (sfb = 0; sfb < num_sfb; sfb += sfb_per_pred_band) { + iusace_write_bits_buf(it_bit_buf, cplx_pred_used[g][sfb], 1); + bit_count += 1; + } + } + } + + if (write_flag) iusace_write_bits_buf(it_bit_buf, pred_dir, 1); + bit_count += 1; + + if (write_flag) iusace_write_bits_buf(it_bit_buf, complex_coef, 1); + bit_count += 1; + + if (complex_coef) { + if (!usac_independency_flg) { + if (write_flag) iusace_write_bits_buf(it_bit_buf, 1, 1); /* use_prev_frame */ + bit_count += 1; + } + } + + if (usac_independency_flg) { + *delta_code_time = 0; + } + + /* Switching mechanism for delta_code_time */ + WORD32 prev_pred_coeff_re_temp1 = 0, prev_pred_coeff_re_temp2 = 0; + WORD32 diff_pred_coeff_re_temp1 = 0, diff_pred_coeff_re_temp2 = 0; + WORD32 prev_pred_coeff_im_temp1 = 0, prev_pred_coeff_im_temp2 = 0; + WORD32 diff_pred_coeff_im_temp1 = 0, diff_pred_coeff_im_temp2 = 0; + + for (i = 0; i < num_win_grps; i++) { + /* delta_code_time = 0*/ + prev_pred_coeff_re_temp1 = 0; + if (complex_coef == 1) { + prev_pred_coeff_im_temp1 = 0; + } + + for (j = 0; j < num_sfb; j += 2) { + if (!usac_independency_flg) { + /* delta_code_time = 1*/ + if (i > 0) { + prev_pred_coeff_re_temp2 = pred_coeffs_re[i - 1][j]; + if (complex_coef == 1) { + prev_pred_coeff_im_temp2 = pred_coeffs_im[i - 1][j]; + } + } else { + prev_pred_coeff_re_temp2 = ptr_prev_alpha_coeff_re[j]; + if (complex_coef == 1) { + prev_pred_coeff_im_temp2 = ptr_prev_alpha_coeff_im[j]; + } + } + } + + if (cplx_pred_used[i][j] == 1) { + /*Differential Huffman coding of real prediction coefficients*/ + diff_pred_coeff_re_temp1 = + pred_coeffs_re[i][j] - prev_pred_coeff_re_temp1; /* delta_code_time = 0 */ + prev_pred_coeff_re_temp1 = pred_coeffs_re[i][j]; /* delta_code_time = 0 */ + if (!usac_independency_flg) { + diff_pred_coeff_re_temp2 = + pred_coeffs_re[i][j] - prev_pred_coeff_re_temp2; /* delta_code_time = 1 */ + } + + /* delta_code_time = 0 */ + length_temp1_re[i][j] = huff_tab[diff_pred_coeff_re_temp1 + 60][0]; + code_word_temp1_re[i][j] = huff_tab[diff_pred_coeff_re_temp1 + 60][1]; + + length_tot1 += length_temp1_re[i][j]; + + if (!usac_independency_flg) { + /*delta_code_time = 1 */ + length_temp2_re[i][j] = huff_tab[diff_pred_coeff_re_temp2 + 60][0]; + code_word_temp2_re[i][j] = huff_tab[diff_pred_coeff_re_temp2 + 60][1]; + + length_tot2 += length_temp2_re[i][j]; + } + + if (complex_coef == 1) { + /*Differential Huffman coding of imaginary prediction coefficients*/ + diff_pred_coeff_im_temp1 = + pred_coeffs_im[i][j] - prev_pred_coeff_im_temp1; /* delta_code_time = 0 */ + prev_pred_coeff_im_temp1 = pred_coeffs_im[i][j]; /* delta_code_time = 0*/ + + if (!usac_independency_flg) { + diff_pred_coeff_im_temp2 = + pred_coeffs_im[i][j] - prev_pred_coeff_im_temp2; /* delta_code_time = 1 */ + } + + /*delta_code_time = 0*/ + length_temp1_im[i][j] = huff_tab[diff_pred_coeff_im_temp1 + 60][0]; + code_word_temp1_im[i][j] = huff_tab[diff_pred_coeff_im_temp1 + 60][1]; + + length_tot1 += length_temp1_im[i][j]; + + if (!usac_independency_flg) { + /*delta_code_time = 1*/ + length_temp2_im[i][j] = huff_tab[diff_pred_coeff_im_temp2 + 60][0]; + code_word_temp2_im[i][j] = huff_tab[diff_pred_coeff_im_temp2 + 60][1]; + + length_tot2 += length_temp2_im[i][j]; + } + } + } else { + pred_coeffs_re[i][j] = 0; + /*delta_code_time = 0*/ + prev_pred_coeff_re_temp1 = pred_coeffs_re[i][j]; + if (complex_coef == 1) { + pred_coeffs_im[i][j] = 0; + /*delta_code_time = 0*/ + prev_pred_coeff_im_temp1 = pred_coeffs_im[i][j]; + } + } + + ptr_prev_alpha_coeff_re[j] = pred_coeffs_re[i][j]; + if (complex_coef == 1) { + ptr_prev_alpha_coeff_im[j] = pred_coeffs_im[i][j]; + } + } + + for (j = num_sfb; j < MAX_SFB_LONG; j++) { + pred_coeffs_re[i][j] = 0; + ptr_prev_alpha_coeff_re[j] = 0; + if (complex_coef == 1) { + pred_coeffs_im[i][j] = 0; + ptr_prev_alpha_coeff_im[j] = 0; + } + } + } + + /*Make a decison on the value of delta_code_time per frame */ + if (!usac_independency_flg) { + // Compare the code-word lengths + if (length_tot1 <= length_tot2) { + *delta_code_time = 0; + } else { + *delta_code_time = 1; + } + + /* Write the value of delta_code_time to bitstream */ + if (write_flag) iusace_write_bits_buf(it_bit_buf, *delta_code_time, 1); + bit_count += 1; + } + + if (*delta_code_time == 0) { + for (i = 0; i < num_win_grps; i++) { + for (j = 0; j < num_sfb; j += 2) { + if (cplx_pred_used[i][j] == 1) { + if (write_flag) + iusace_write_bits_buf(it_bit_buf, code_word_temp1_re[i][j], + (UWORD8)length_temp1_re[i][j]); + bit_count += length_temp1_re[i][j]; + + if (complex_coef == 1) { + if (write_flag) + iusace_write_bits_buf(it_bit_buf, code_word_temp1_im[i][j], + (UWORD8)length_temp1_im[i][j]); + bit_count += length_temp1_im[i][j]; + } + } + } + } + } else { + for (i = 0; i < num_win_grps; i++) { + for (j = 0; j < num_sfb; j += 2) { + if (cplx_pred_used[i][j] == 1) { + if (write_flag) + iusace_write_bits_buf(it_bit_buf, code_word_temp2_re[i][j], + (UWORD8)length_temp2_re[i][j]); + bit_count += length_temp2_re[i][j]; + + if (complex_coef == 1) { + if (write_flag) + iusace_write_bits_buf(it_bit_buf, code_word_temp2_im[i][j], + (UWORD8)length_temp2_im[i][j]); + bit_count += length_temp2_im[i][j]; + } + } + } + } + } + + return bit_count; +} + +WORD32 iusace_write_cpe(ia_sfb_params_struct *pstr_sfb_prms, ia_bit_buf_struct *it_bit_buf, + WORD32 *tns_data_present, WORD32 const usac_independency_flg, + ia_usac_encoder_config_struct *pstr_usac_config, + ia_usac_data_struct *pstr_usac_data, WORD32 ch) { + WORD32 bit_count = 0; + WORD32 ms_mask = pstr_usac_data->str_ms_info[ch].ms_mask; + WORD32 common_max_sfb = 1; + WORD32 tns_active = tns_data_present[0] || tns_data_present[1]; + ia_tns_info *pstr_tns_info = pstr_usac_data->pstr_tns_info[ch]; + (VOID) pstr_usac_config; + + iusace_write_bits_buf(it_bit_buf, tns_active, 1); + bit_count += 1; + + iusace_write_bits_buf(it_bit_buf, pstr_sfb_prms->common_win[ch], 1); + bit_count += 1; + + if (pstr_sfb_prms->max_sfb[ch] != pstr_sfb_prms->max_sfb[ch + 1]) { + common_max_sfb = 0; + } + + if (pstr_sfb_prms->common_win[ch]) { + bit_count += iusace_write_ics_info(it_bit_buf, pstr_sfb_prms, ch); + + iusace_write_bits_buf(it_bit_buf, common_max_sfb, 1); + bit_count += 1; + + if (common_max_sfb == 0) { + if (pstr_sfb_prms->window_sequence[ch] != EIGHT_SHORT_SEQUENCE) { + iusace_write_bits_buf(it_bit_buf, pstr_sfb_prms->max_sfb[ch + 1], 6); + bit_count += 6; + } else { + iusace_write_bits_buf(it_bit_buf, pstr_sfb_prms->max_sfb[ch + 1], 4); + bit_count += 4; + } + } + + pstr_sfb_prms->max_sfb_ste = MAX(pstr_sfb_prms->max_sfb[ch], pstr_sfb_prms->max_sfb[ch + 1]); + + bit_count += + iusace_write_ms_data(it_bit_buf, ms_mask, pstr_usac_data->str_ms_info[ch].ms_used, + pstr_sfb_prms->num_window_groups[ch], pstr_sfb_prms->max_sfb_ste); + + { + if (ms_mask == 3) { + bit_count += iusace_write_cplx_pred_data( + it_bit_buf, pstr_sfb_prms->num_window_groups[ch], pstr_sfb_prms->max_sfb_ste, + pstr_usac_data->complex_coef[ch], pstr_usac_data->pred_coef_re[ch], + pstr_usac_data->pred_coef_im[ch], iusace_huffman_code_table, usac_independency_flg, + pstr_usac_data->pred_dir_idx[ch], pstr_usac_data->cplx_pred_used[ch], + pstr_usac_data->cplx_pred_all[ch], pstr_usac_data->pred_coef_re_prev[ch], + pstr_usac_data->pred_coef_im_prev[ch], &pstr_usac_data->delta_code_time[ch]); + } + } + } + + if (tns_active) { + WORD32 common_tns = 0; + WORD32 tns_on_lr = 1; + WORD32 tns_present_both = tns_data_present[0] && tns_data_present[1]; + WORD32 tns_data_present1 = tns_data_present[1]; + + if (pstr_sfb_prms->common_win[ch]) { + iusace_write_bits_buf(it_bit_buf, common_tns, 1); + bit_count += 1; + } + + iusace_write_bits_buf(it_bit_buf, tns_on_lr, 1); + bit_count += 1; + + if (common_tns) { + bit_count += + iusace_write_tns_data(it_bit_buf, pstr_tns_info, pstr_sfb_prms->window_sequence[ch], 0); + } else { + iusace_write_bits_buf(it_bit_buf, tns_present_both, 1); + bit_count += 1; + + if (!tns_present_both) { + iusace_write_bits_buf(it_bit_buf, tns_data_present1, 1); + bit_count += 1; + } + } + } + + return (bit_count); +} + +WORD32 iusace_write_fd_data(ia_bit_buf_struct *it_bit_buf, ia_sfb_params_struct *pstr_sfb_prms, + WORD32 num_fac_bits, WORD32 usac_independency_flg, + ia_usac_data_struct *pstr_usac_data, + ia_usac_encoder_config_struct *pstr_usac_config, WORD32 ch_idx, + WORD32 ele_id, WORD32 idx) { + WORD32 bit_count = 0; + WORD32 fac_data_present = (num_fac_bits > 0) ? 1 : 0; + WORD16 *ptr_fac_data = pstr_usac_data->fac_out_stream[ch_idx]; + + WORD32 is_noise_filling = pstr_usac_data->noise_filling[ele_id]; + WORD32 common_window = pstr_sfb_prms->common_win[ch_idx]; + ia_usac_quant_info_struct *pstr_quant_info = &(pstr_usac_data->str_quant_info[idx]); + ia_tns_info *pstr_tns_info = pstr_usac_data->pstr_tns_info[ch_idx]; + WORD32 global_gain = pstr_usac_data->str_quant_info[idx].scale_factor[0]; + + iusace_write_bits_buf(it_bit_buf, global_gain, 8); + bit_count += 8; + + if (is_noise_filling) { + iusace_write_bits_buf(it_bit_buf, pstr_usac_data->noise_level[idx], 3); + + iusace_write_bits_buf(it_bit_buf, pstr_usac_data->noise_offset[idx], 5); + bit_count += 8; + } + + if (!common_window) { + bit_count += iusace_write_ics_info(it_bit_buf, pstr_sfb_prms, ch_idx); + } + +#if DEBUG_DUMP + WORD32 bit_count_start = bit_count; +#endif + + bit_count += iusace_write_scf_data( + it_bit_buf, pstr_sfb_prms->max_sfb[ch_idx], pstr_sfb_prms->num_sfb[ch_idx], + pstr_quant_info->scale_factor, pstr_sfb_prms->num_window_groups[ch_idx], global_gain, + iusace_huffman_code_table); + +#if DEBUG_DUMP + WORD32 bit_count_mid_1 = bit_count; +#endif + + if (pstr_tns_info != NULL && pstr_tns_info->tns_data_present == 1) { + bit_count += iusace_write_tns_data(it_bit_buf, pstr_tns_info, + pstr_sfb_prms->window_sequence[ch_idx], 0); + } + + if (!usac_independency_flg) { + iusace_write_bits_buf(it_bit_buf, pstr_quant_info->reset, 1); + bit_count += 1; + } + +#if DEBUG_DUMP + WORD32 bit_count_mid_2 = bit_count; +#endif + if (pstr_quant_info->max_spec_coeffs == FRAME_LEN_SHORT_768) { + pstr_quant_info->max_spec_coeffs = pstr_quant_info->max_spec_coeffs; + } + bit_count += iusace_arith_enc_spec( + it_bit_buf, pstr_sfb_prms->window_sequence[ch_idx], pstr_quant_info->quant_degroup, + pstr_quant_info->max_spec_coeffs, pstr_quant_info->c_pres, pstr_quant_info->c_prev, + &(pstr_quant_info->arith_size_prev), usac_independency_flg || pstr_quant_info->reset, + pstr_usac_config->ccfl); + +#if DEBUG_DUMP + WORD32 bit_count_end = bit_count; +#endif + + iusace_write_bits_buf(it_bit_buf, fac_data_present, 1); + bit_count += 1; + + if (fac_data_present) { + WORD32 i; + for (i = 0; i < num_fac_bits; i += 8) { + WORD32 bits_to_write = MIN(8, num_fac_bits - i); + iusace_write_bits_buf(it_bit_buf, ptr_fac_data[i / 8] >> (8 - bits_to_write), + (UWORD8)bits_to_write); + } + bit_count += num_fac_bits; + } + +#if DEBUG_DUMP + fprintf(out_file, "%d\t", + bit_count - (bit_count_mid_1 - bit_count_start) - (bit_count_end - bit_count_mid_2)); +#endif + + return (bit_count); +} + +WORD32 iusace_count_fd_bits(ia_sfb_params_struct *pstr_sfb_prms, + ia_usac_data_struct *pstr_usac_data, WORD32 usac_independency_flg, + ia_usac_encoder_config_struct *pstr_usac_config, WORD32 ch_idx, + WORD32 idx) { + WORD32 bit_count = 0; + ia_usac_quant_info_struct *pstr_quant_info = &pstr_usac_data->str_quant_info[idx]; + WORD32 window_sequence = pstr_sfb_prms->window_sequence[ch_idx]; + WORD32 global_gain = pstr_quant_info->scale_factor[0]; + WORD32 max_sfb = pstr_sfb_prms->max_sfb[ch_idx]; + WORD32 num_sfb = pstr_sfb_prms->num_sfb[ch_idx]; + WORD32 num_win_grps = pstr_sfb_prms->num_window_groups[ch_idx]; + + bit_count += iusace_write_scf_data(NULL, max_sfb, num_sfb, pstr_quant_info->scale_factor, + num_win_grps, global_gain, iusace_huffman_code_table); + + WORD32 temp_c_pres[516], temp_c_prev[516], temp_size = pstr_quant_info->arith_size_prev; + memcpy(temp_c_pres, pstr_quant_info->c_pres, 516 * sizeof(pstr_quant_info->c_pres[0])); + memcpy(temp_c_prev, pstr_quant_info->c_prev, 516 * sizeof(pstr_quant_info->c_prev[0])); + bit_count += iusace_arith_enc_spec( + NULL, window_sequence, pstr_quant_info->quant_degroup, pstr_quant_info->max_spec_coeffs, + temp_c_pres, temp_c_prev, &(temp_size), usac_independency_flg || pstr_quant_info->reset, + pstr_usac_config->ccfl); + + return (bit_count); +} + +WORD32 iusace_write_fill_ele(ia_bit_buf_struct *it_bit_buf, WORD32 num_bits) { + WORD32 write_flag = (it_bit_buf != NULL); + WORD32 bit_count = 0; + + if (num_bits <= 8) { + if (write_flag) { + iusace_write_bits_buf(it_bit_buf, 0, 1); + } + bit_count++; + num_bits--; + } else { + if (write_flag) { + iusace_write_bits_buf(it_bit_buf, 1, 1); + } + bit_count++; + num_bits--; + + if (num_bits <= 8) { + if (write_flag) { + iusace_write_bits_buf(it_bit_buf, 1, 1); + } + bit_count++; + num_bits--; + } else { + WORD32 bytes_to_write = 0; + if (write_flag) { + iusace_write_bits_buf(it_bit_buf, 0, 1); + } + bit_count++; + num_bits--; + bytes_to_write = num_bits >> 3; + + if (bytes_to_write > 255) { + bytes_to_write -= 3; + if (write_flag) { + iusace_write_bits_buf(it_bit_buf, 255, 8); + } + if (write_flag) { + iusace_write_bits_buf(it_bit_buf, bytes_to_write - 253, 16); + } + bit_count += 24; + num_bits -= 24; + } else { + bytes_to_write--; + if (write_flag) { + iusace_write_bits_buf(it_bit_buf, bytes_to_write, 8); + } + bit_count += 8; + num_bits -= 8; + } + + while (bytes_to_write > 0) { + if (write_flag) { + iusace_write_bits_buf(it_bit_buf, 0xA9, 8); + } + bit_count += 8; + num_bits -= 8; + bytes_to_write--; + } + } + } + return bit_count; +} diff --git a/encoder/iusace_write_bitstream.h b/encoder/iusace_write_bitstream.h new file mode 100644 index 0000000..4000da9 --- /dev/null +++ b/encoder/iusace_write_bitstream.h @@ -0,0 +1,62 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +WORD32 iusace_write_ics_info(ia_bit_buf_struct *it_bit_buf, ia_sfb_params_struct *pstr_sfb_prms, + WORD32 ch); + +WORD32 iusace_write_cpe(ia_sfb_params_struct *pstr_sfb_prms, ia_bit_buf_struct *it_bit_buf, + WORD32 *tns_data_present, WORD32 const usac_independency_flg, + ia_usac_encoder_config_struct *ptr_usac_config, + ia_usac_data_struct *ptr_usac_data, WORD32 ch); + +WORD32 iusace_write_fd_data(ia_bit_buf_struct *it_bit_buf, ia_sfb_params_struct *pstr_sfb_prms, + WORD32 num_fac_bits, WORD32 usac_independency_flg, + ia_usac_data_struct *ptr_usac_data, + ia_usac_encoder_config_struct *ptr_usac_config, WORD32 ch_idx, + WORD32 ele_id, WORD32 idx); + +WORD32 iusace_count_fd_bits(ia_sfb_params_struct *pstr_sfb_prms, + ia_usac_data_struct *ptr_usac_data, WORD32 usac_independency_flg, + ia_usac_encoder_config_struct *ptr_usac_config, WORD32 ch_idx, + WORD32 idx); + +WORD32 iusace_write_fill_ele(ia_bit_buf_struct *it_bit_buf, WORD32 num_bits); + +WORD32 iusace_write_tns_data(ia_bit_buf_struct *it_bit_buf, ia_tns_info *pstr_tns_info, + WORD32 window_sequence, WORD32 core_mode); + +WORD32 iusace_write_cplx_pred_data(ia_bit_buf_struct *it_bit_buf, WORD32 num_win_grps, + WORD32 num_sfb, WORD32 complex_coef, + WORD32 pred_coeffs_re[MAX_SHORT_WINDOWS][MAX_SFB_LONG], + WORD32 pred_coeffs_im[MAX_SHORT_WINDOWS][MAX_SFB_LONG], + const WORD32 huff_tab[CODE_BOOK_ALPHA_LAV][2], + WORD32 const usac_independency_flg, WORD32 pred_dir, + WORD32 cplx_pred_used[MAX_SHORT_WINDOWS][MAX_SFB_LONG], + WORD32 cplx_pred_all, WORD32 *ptr_prev_alpha_coeff_re, + WORD32 *ptr_prev_alpha_coeff_im, WORD32 *delta_code_time); + +WORD32 iusace_write_ms_data(ia_bit_buf_struct *it_bit_buf, WORD32 ms_mask, + WORD32 ms_used[MAX_SHORT_WINDOWS][MAX_SFB_LONG], WORD32 num_win_grps, + WORD32 nr_of_sfb); + +WORD32 iusace_write_scf_data(ia_bit_buf_struct *it_bit_buf, WORD32 max_sfb, WORD32 num_sfb, + const WORD32 *scale_factors, WORD32 num_win_grps, WORD32 global_gain, + const WORD32 huff_tab[CODE_BOOK_ALPHA_LAV][2]); diff --git a/encoder/ixheaace_aac_constants.h b/encoder/ixheaace_aac_constants.h index 084aec6..40e779a 100644 --- a/encoder/ixheaace_aac_constants.h +++ b/encoder/ixheaace_aac_constants.h @@ -76,7 +76,6 @@ typedef struct { WORD32 num_bit; /* number of bits in buffer */ WORD32 size; /* buffer size in bytes */ WORD32 current_bit; /* current bit position in bit stream */ - WORD32 numByte; /* number of bytes read/written (only file) */ } ixheaace_bitstream_params; /* bits in byte (char) */ @@ -115,8 +114,8 @@ typedef struct { #define NUM_CHANS_MONO (1) #define NUM_CHANS_STEREO (2) -#define MAX_NUM_CHANNELS (6) -#define MIN_NUM_CHANNELS (1) +#define MAX_NUM_CORE_CODER_CHANNELS (6) +#define MIN_NUM_CORE_CODER_CHANNELS (1) /*-------------------------- defines --------------------------------------*/ #define BUFFERSIZE 1024 /* anc data */ \ No newline at end of file diff --git a/encoder/ixheaace_adjust_threshold.c b/encoder/ixheaace_adjust_threshold.c index 4a63bb7..670a33e 100644 --- a/encoder/ixheaace_adjust_threshold.c +++ b/encoder/ixheaace_adjust_threshold.c @@ -25,6 +25,10 @@ #include "ixheaac_type_def.h" #include "ixheaac_constants.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" #include "ixheaace_api.h" #include "ixheaace_aac_constants.h" #include "ixheaace_psy_const.h" diff --git a/encoder/ixheaace_api.c b/encoder/ixheaace_api.c index abcda21..b5ff57c 100644 --- a/encoder/ixheaace_api.c +++ b/encoder/ixheaace_api.c @@ -39,6 +39,17 @@ #include "iusace_bitbuffer.h" +/* DRC */ +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" +#include "impd_drc_uni_drc_eq.h" +#include "impd_drc_uni_drc_filter_bank.h" +#include "impd_drc_gain_enc.h" +#include "impd_drc_struct_def.h" +#include "impd_drc_enc.h" + #include "ixheaace_sbr_header.h" #include "ixheaace_sbr_def.h" #include "ixheaace_resampler.h" @@ -56,8 +67,13 @@ #include "ixheaace_definitions.h" #include "ixheaace_api.h" #include "ixheaace_memory_standards.h" +#include "iusace_block_switch_const.h" +#include "iusace_block_switch_struct_def.h" #include "iusace_cnst.h" +#include "iusace_tns_usac.h" +#include "iusace_psy_mod.h" #include "iusace_config.h" +#include "iusace_arith_enc.h" #include "ixheaace_version_number.h" #include "ixheaace_adjust_threshold_data.h" @@ -72,10 +88,15 @@ #include "ixheaace_common_rom.h" #include "ixheaace_psy_mod.h" +#include "iusace_fd_qc_util.h" +#include "iusace_fd_quant.h" +#include "iusace_ms.h" +#include "iusace_signal_classifier.h" #include "ixheaace_sbr_header.h" #include "ixheaace_config.h" #include "ixheaace_asc_write.h" +#include "iusace_main.h" #include "ixheaace_stereo_preproc.h" #include "ixheaace_enc_main.h" #include "ixheaace_qc_util.h" @@ -116,6 +137,42 @@ #include "ixheaace_write_adts_adif.h" +/* Ensure all memory are aligned */ +#define IXHEAACE_ALIGN_MEMORY(address, alignment) \ + ((WORD8 *)((address + (alignment - 1)) & ~(alignment - 1))) + +static WORD32 iusace_scratch_size(VOID) { + WORD32 scr_size; + scr_size = USACE_MAX_SCR_SIZE; + return scr_size; +} + +static WORD32 iusace_calc_pers_buf_sizes(ixheaace_api_struct *pstr_api_struct) { + WORD32 pers_size = 0; + ia_usac_encoder_config_struct *pstr_config = &pstr_api_struct->config[0].usac_config; + + pers_size += pstr_config->channels * sizeof(FLOAT32 *); + pers_size += pstr_config->channels * sizeof(FLOAT32 *); + pers_size += pstr_config->channels * sizeof(FLOAT32 *); + pers_size += pstr_config->channels * sizeof(FLOAT32 *); + + pers_size += ((2 * pstr_config->ccfl) * sizeof(FLOAT32) * pstr_config->channels); + pers_size += ((2 * pstr_config->drc_frame_size) * sizeof(FLOAT32) * pstr_config->channels); + + pers_size += 2 * pstr_config->ccfl * sizeof(FLOAT64) * pstr_config->channels; + + pers_size += pstr_config->ccfl * sizeof(FLOAT64) * pstr_config->channels; + + pers_size += 2 * pstr_config->ccfl * sizeof(FLOAT64) * pstr_config->channels; + + pers_size += 3 * pstr_config->ccfl * sizeof(FLOAT64) * pstr_config->channels; + + if (pstr_config->tns_select != 0) pers_size += sizeof(ia_tns_info) * pstr_config->channels; + + pers_size += sizeof(ia_usac_td_encoder_struct) * pstr_config->channels; + return pers_size; +} + static WORD32 ia_enhaacplus_enc_sizeof_delay_buffer(FLAG flag_framelength_small, WORD32 aot, WORD32 resamp_idx, WORD32 delay_buf_size, FLAG mps_enable) { @@ -245,7 +302,7 @@ static VOID ia_enhaacplus_enc_find_channel_config(WORD32 *num_bs_elements, WORD3 WORD32 *element_instance_tag, WORD32 i_num_coupling_chan, WORD32 i_channel_mask) { - WORD32 slot = 0, i; + WORD32 i; WORD32 slots_for_elements[2 * MAXIMUM_BS_ELE]; *num_bs_elements = 0; @@ -257,7 +314,6 @@ static VOID ia_enhaacplus_enc_find_channel_config(WORD32 *num_bs_elements, WORD3 chan_config[*num_bs_elements] = 1; element_type[*num_bs_elements] = ID_SCE; element_slot[*num_bs_elements] = slots_for_elements[FRONT_CENTER]; - slot += chan_config[*num_bs_elements]; element_instance_tag[*num_bs_elements] = 0; (*num_bs_elements)++; } @@ -267,7 +323,6 @@ static VOID ia_enhaacplus_enc_find_channel_config(WORD32 *num_bs_elements, WORD3 chan_config[*num_bs_elements] = 2; element_type[*num_bs_elements] = ID_CPE; element_slot[*num_bs_elements] = slots_for_elements[FRONT_LEFT_RIGHT]; - slot += chan_config[*num_bs_elements]; element_instance_tag[*num_bs_elements] = 0; (*num_bs_elements)++; } @@ -277,7 +332,6 @@ static VOID ia_enhaacplus_enc_find_channel_config(WORD32 *num_bs_elements, WORD3 chan_config[*num_bs_elements] = 2; element_type[*num_bs_elements] = ID_CPE; element_slot[*num_bs_elements] = slots_for_elements[BACK_LEFT_RIGHT]; - slot += chan_config[*num_bs_elements]; element_instance_tag[*num_bs_elements] = 1; (*num_bs_elements)++; } @@ -287,8 +341,6 @@ static VOID ia_enhaacplus_enc_find_channel_config(WORD32 *num_bs_elements, WORD3 chan_config[*num_bs_elements] = 2; element_type[*num_bs_elements] = ID_CPE; element_slot[*num_bs_elements] = slots_for_elements[BACK_LR_OF_CENTER]; - ; - slot += chan_config[*num_bs_elements]; element_instance_tag[*num_bs_elements] = 2; (*num_bs_elements)++; } @@ -298,7 +350,6 @@ static VOID ia_enhaacplus_enc_find_channel_config(WORD32 *num_bs_elements, WORD3 chan_config[*num_bs_elements] = 1; element_type[*num_bs_elements] = ID_LFE; element_slot[*num_bs_elements] = slots_for_elements[LFE_CHANNEL]; - slot += chan_config[*num_bs_elements]; element_instance_tag[*num_bs_elements] = 0; (*num_bs_elements)++; } @@ -309,8 +360,6 @@ static VOID ia_enhaacplus_enc_find_channel_config(WORD32 *num_bs_elements, WORD3 chan_config[*num_bs_elements] = 1; element_type[*num_bs_elements] = ID_CCE; element_slot[*num_bs_elements] = slots_for_elements[COUPLING_CH + i]; - slot += chan_config[*num_bs_elements]; - // element_instance_tag[*num_bs_elements] = i; element_instance_tag[*num_bs_elements] = i_num_coupling_chan - i - 1; (*num_bs_elements)++; } @@ -395,6 +444,7 @@ static WORD32 ixheaace_validate_channel_mask(WORD32 ch_mask, WORD32 num_ch) { static VOID ixheaace_set_default_config(ixheaace_api_struct *pstr_api_struct, ixheaace_input_config *pstr_input_config) { + ia_usac_encoder_config_struct *pstr_usac_config = &pstr_api_struct->config[0].usac_config; WORD32 i; for (i = 0; i < MAXIMUM_BS_ELE; i++) { @@ -426,7 +476,22 @@ static VOID ixheaace_set_default_config(ixheaace_api_struct *pstr_api_struct, pstr_api_struct->config[i].use_mps = USE_MPS_PARAM_DEFAULT_VALUE; pstr_api_struct->config[i].mps_tree_config = USE_MPS_TREE_CONFIG_PARAM_DEFAULT_VALUE; } - + if (pstr_input_config->aot == AOT_USAC) { + memset(pstr_usac_config, 0, sizeof(*pstr_usac_config)); + pstr_usac_config->channels = NUM_CHANNELS_CONFIG_PARAM_DEFAULT_VALUE; + pstr_usac_config->sample_rate = USAC_SAMP_FREQ_CONFIG_PARAM_DEFAULT_VALUE; + pstr_usac_config->core_sample_rate = USAC_SAMP_FREQ_CONFIG_PARAM_DEFAULT_VALUE; + pstr_usac_config->native_sample_rate = USAC_SAMP_FREQ_CONFIG_PARAM_DEFAULT_VALUE; + pstr_usac_config->sbr_pvc_active = USAC_SBR_PVC_DEFAULT_VALUE; + pstr_usac_config->sbr_inter_tes_active = USAC_SBR_INTER_TES_DEFAULT_VALUE; + pstr_usac_config->sbr_harmonic = USAC_SBR_HARMONIC_DEFAULT_VALUE; + pstr_usac_config->bit_rate = USAC_BITRATE_DEFAULT_VALUE; + pstr_usac_config->use_fill_element = USAC_FILL_ELEMENT_DEFAULT_VALUE; + pstr_usac_config->use_drc_element = USAC_DRC_DEFAULT_VALUE; + pstr_usac_config->cmplx_pred_flag = USAC_COMPLEX_PREDECTION_DEFAULT_VALUE; + pstr_usac_config->tns_select = USAC_TNS_DEFAULT_VALUE; + pstr_usac_config->flag_noiseFilling = USAC_FLAG_NOISE_FILLING_DEFAULT_VALUE; + } /* Initialize table pointers */ ia_enhaacplus_enc_init_aac_tabs(&(pstr_api_struct->pstr_aac_tabs)); ia_enhaacplus_enc_init_sbr_tabs(&(pstr_api_struct->spectral_band_replication_tabs)); @@ -440,6 +505,9 @@ static VOID ixheaace_validate_config_params(ixheaace_input_config *pstr_input_co pstr_input_config->aot != AOT_SBR && pstr_input_config->aot != AOT_USAC) { pstr_input_config->aot = AOT_AAC_LC; } + if (1 == pstr_input_config->usac_en) { + pstr_input_config->aot = AOT_USAC; + } pstr_input_config->i_native_samp_freq = pstr_input_config->i_samp_freq; if (pstr_input_config->aot == AOT_USAC) { if (pstr_input_config->i_samp_freq < 9391) { @@ -479,8 +547,8 @@ static VOID ixheaace_validate_config_params(ixheaace_input_config *pstr_input_co } } - if ((pstr_input_config->i_channels < MIN_NUM_CHANNELS) || - (pstr_input_config->i_channels > MAX_NUM_CHANNELS)) { + if ((pstr_input_config->i_channels < MIN_NUM_CORE_CODER_CHANNELS) || + (pstr_input_config->i_channels > MAX_NUM_CORE_CODER_CHANNELS)) { pstr_input_config->i_channels = 1; } if (pstr_input_config->esbr_flag != 1 && pstr_input_config->esbr_flag != 0) { @@ -501,6 +569,18 @@ static VOID ixheaace_validate_config_params(ixheaace_input_config *pstr_input_co if (pstr_input_config->aot != AOT_AAC_ELD && pstr_input_config->aot != AOT_USAC) { pstr_input_config->i_use_mps = 0; } + if (pstr_input_config->aot == AOT_USAC && pstr_input_config->i_use_mps == 1) { + if (pstr_input_config->ccfl_idx < SBR_8_3) { + pstr_input_config->ccfl_idx = SBR_2_1; + } + } + if (AOT_USAC == pstr_input_config->aot) { + if ((pstr_input_config->i_channels != 2) || (pstr_input_config->i_samp_freq > 48000)) { + // Num qmf bands is mapped only till 48000. Hence, disable mps if fs > 48000 or if input + // channels is not 2 + pstr_input_config->i_use_mps = 0; + } + } if (pstr_input_config->i_use_mps == 1) { if (pstr_input_config->i_channels == 2) { if (pstr_input_config->i_mps_tree_config != TREE_212) { @@ -521,8 +601,118 @@ static VOID ixheaace_validate_config_params(ixheaace_input_config *pstr_input_co pstr_input_config->i_use_adts = 0; pstr_input_config->i_use_es = 1; } + if (pstr_input_config->aot == AOT_USAC) { + if (pstr_input_config->codec_mode != USAC_SWITCHED && + pstr_input_config->codec_mode != USAC_ONLY_FD && + pstr_input_config->codec_mode != USAC_ONLY_TD) { + pstr_input_config->codec_mode = USAC_ONLY_FD; + } + if (pstr_input_config->ccfl_idx < NO_SBR_CCFL_768 || pstr_input_config->ccfl_idx > SBR_4_1) { + pstr_input_config->ccfl_idx = NO_SBR_CCFL_1024; // default value + } + if (pstr_input_config->cplx_pred != 1 && pstr_input_config->cplx_pred != 0) { + pstr_input_config->cplx_pred = 0; + } + if (pstr_input_config->use_drc_element != 0 && pstr_input_config->use_drc_element != 1) { + pstr_input_config->use_drc_element = 0; + } - { + if (pstr_input_config->hq_esbr != 0 && pstr_input_config->hq_esbr != 1) { + pstr_input_config->hq_esbr = 0; + } + if (pstr_input_config->harmonic_sbr != 0 && pstr_input_config->harmonic_sbr != 1) { + pstr_input_config->harmonic_sbr = 0; + } + if (pstr_input_config->pvc_active != 0 && pstr_input_config->pvc_active != 1) { + pstr_input_config->pvc_active = 0; + } + if (pstr_input_config->inter_tes_active != 0 && pstr_input_config->inter_tes_active != 1) { + pstr_input_config->inter_tes_active = 0; + } + if ((pstr_input_config->ccfl_idx != 3 && pstr_input_config->ccfl_idx != 4)) { + pstr_input_config->harmonic_sbr = 0; + } + if (pstr_input_config->harmonic_sbr != 1) { + pstr_input_config->hq_esbr = 0; + } + if (pstr_input_config->i_bitrate != 64000 && pstr_input_config->i_bitrate != 96000) { + pstr_input_config->i_bitrate = USAC_BITRATE_DEFAULT_VALUE; + } + { + if (pstr_input_config->i_bitrate < MINIMUM_BITRATE * pstr_input_config->i_channels) { + pstr_input_config->i_bitrate = MINIMUM_BITRATE * pstr_input_config->i_channels; + } + if (pstr_input_config->ccfl_idx == NO_SBR_CCFL_768 || + pstr_input_config->ccfl_idx == NO_SBR_CCFL_1024) { + if (pstr_input_config->i_bitrate > + (6 * pstr_input_config->i_samp_freq * pstr_input_config->i_channels)) { + pstr_input_config->i_bitrate = + (6 * pstr_input_config->i_samp_freq * pstr_input_config->i_channels); + } + } else if (pstr_input_config->ccfl_idx == SBR_8_3) { + if (pstr_input_config->i_bitrate > + (6 * ((pstr_input_config->i_samp_freq * 3) / 8) * pstr_input_config->i_channels)) { + pstr_input_config->i_bitrate = + (6 * ((pstr_input_config->i_samp_freq * 3) / 8) * pstr_input_config->i_channels); + } + } else if (pstr_input_config->ccfl_idx == SBR_2_1) { + if (pstr_input_config->i_bitrate > + (6 * (pstr_input_config->i_samp_freq / 2) * pstr_input_config->i_channels)) { + pstr_input_config->i_bitrate = + (6 * (pstr_input_config->i_samp_freq / 2) * pstr_input_config->i_channels); + } + } else if (pstr_input_config->ccfl_idx == SBR_4_1) { + if (pstr_input_config->i_bitrate > + (6 * (pstr_input_config->i_samp_freq / 4) * pstr_input_config->i_channels)) { + pstr_input_config->i_bitrate = + (6 * (pstr_input_config->i_samp_freq / 4) * pstr_input_config->i_channels); + } + } + } + + { + if (pstr_input_config->i_samp_freq > 64000) + { + pstr_input_config->codec_mode = USAC_ONLY_FD; + pstr_input_config->ccfl_idx = NO_SBR_CCFL_1024; + pstr_input_config->esbr_flag = 0; + } + if ((pstr_input_config->codec_mode == USAC_SWITCHED || + pstr_input_config->codec_mode == USAC_ONLY_TD) && + pstr_input_config->i_samp_freq > 24000) { + if (pstr_input_config->ccfl_idx == NO_SBR_CCFL_768) { + pstr_input_config->ccfl_idx = SBR_8_3; // Use 8:3 eSBR + } + if (pstr_input_config->ccfl_idx == NO_SBR_CCFL_1024) { + pstr_input_config->ccfl_idx = SBR_2_1; // Use 2:1 eSBR + } + } + + if (pstr_input_config->codec_mode == USAC_ONLY_FD && + pstr_input_config->i_samp_freq > 24000 && pstr_input_config->esbr_flag && + pstr_input_config->i_bitrate <= MAX_USAC_ESBR_BITRATE) { + if (pstr_input_config->ccfl_idx == NO_SBR_CCFL_768) { + pstr_input_config->ccfl_idx = SBR_8_3; // Use 8:3 eSBR + } + if (pstr_input_config->ccfl_idx == NO_SBR_CCFL_1024) { + pstr_input_config->ccfl_idx = SBR_2_1; // Use 2:1 eSBR + } + } + + if (pstr_input_config->ccfl_idx == NO_SBR_CCFL_768 || + pstr_input_config->ccfl_idx == SBR_8_3) { + pstr_input_config->frame_length = LEN_SUPERFRAME_768; + } else { + pstr_input_config->frame_length = LEN_SUPERFRAME; + } + } + } else { + pstr_input_config->cplx_pred = 0; + pstr_input_config->harmonic_sbr = 0; + pstr_input_config->pvc_active = 0; + pstr_input_config->inter_tes_active = 0; + pstr_input_config->use_drc_element = 0; + pstr_input_config->hq_esbr = 0; if (pstr_input_config->i_channels != 2 && pstr_input_config->aot == AOT_PS) { pstr_input_config->aot = AOT_SBR; } @@ -575,7 +765,7 @@ static VOID ixheaace_validate_config_params(ixheaace_input_config *pstr_input_co static IA_ERRORCODE ixheaace_set_config_params(ixheaace_api_struct *pstr_api_struct, ixheaace_input_config *pstr_input_config) { WORD32 ele_idx; - + ia_usac_encoder_config_struct *pstr_usac_config = &pstr_api_struct->config[0].usac_config; ixheaace_validate_config_params(pstr_input_config); if (pstr_input_config->ui_pcm_wd_sz != 16) { @@ -669,10 +859,117 @@ static IA_ERRORCODE ixheaace_set_config_params(ixheaace_api_struct *pstr_api_str if ((pstr_input_config->i_samp_freq < 6000) || (pstr_input_config->i_samp_freq > 96000)) { return (IA_EXHEAACE_CONFIG_FATAL_SAMP_FREQ); } + pstr_api_struct->usac_en = 1; + pstr_usac_config->codec_mode = pstr_input_config->codec_mode; + pstr_usac_config->channels = pstr_input_config->i_channels; + + pstr_usac_config->core_sample_rate = pstr_input_config->i_samp_freq; + pstr_usac_config->sample_rate = pstr_input_config->i_samp_freq; + pstr_usac_config->native_sample_rate = pstr_input_config->i_native_samp_freq; + + pstr_usac_config->ui_pcm_wd_sz = pstr_input_config->ui_pcm_wd_sz; + pstr_usac_config->ccfl_idx = pstr_input_config->ccfl_idx; + pstr_usac_config->bit_rate = pstr_input_config->i_bitrate; + pstr_usac_config->basic_bitrate = pstr_input_config->i_bitrate; + pstr_usac_config->tns_select = pstr_input_config->aac_config.use_tns; + pstr_usac_config->cmplx_pred_flag = pstr_input_config->cplx_pred; + pstr_usac_config->flag_noiseFilling = pstr_input_config->aac_config.noise_filling; + pstr_usac_config->sbr_pvc_active = pstr_input_config->pvc_active; + pstr_usac_config->sbr_harmonic = pstr_input_config->harmonic_sbr; + pstr_usac_config->hq_esbr = pstr_input_config->hq_esbr; + pstr_usac_config->sbr_inter_tes_active = pstr_input_config->inter_tes_active; pstr_api_struct->config[0].chmode_nchannels = pstr_api_struct->config[0].i_channels; + + switch (pstr_input_config->ccfl_idx) { + case NO_SBR_CCFL_768: + pstr_usac_config->ccfl = LEN_SUPERFRAME_768; + pstr_usac_config->in_frame_length = LEN_SUPERFRAME_768; + pstr_usac_config->sbr_enable = 0; + pstr_usac_config->drc_frame_size = LEN_SUPERFRAME_768; + break; + case NO_SBR_CCFL_1024: + pstr_usac_config->ccfl = LEN_SUPERFRAME; + pstr_usac_config->in_frame_length = LEN_SUPERFRAME; + pstr_usac_config->sbr_enable = 0; + pstr_usac_config->drc_frame_size = LEN_SUPERFRAME; + break; + case SBR_8_3: + pstr_usac_config->ccfl = LEN_SUPERFRAME_768; + pstr_usac_config->in_frame_length = (LEN_SUPERFRAME_768 * 8) / 3; + pstr_usac_config->sbr_enable = 1; + pstr_usac_config->drc_frame_size = (LEN_SUPERFRAME_768 * 8) / 3; + break; + case SBR_2_1: + pstr_usac_config->ccfl = LEN_SUPERFRAME; + pstr_usac_config->in_frame_length = (LEN_SUPERFRAME * 2); + pstr_usac_config->sbr_enable = 1; + pstr_usac_config->drc_frame_size = (LEN_SUPERFRAME * 2); + break; + case SBR_4_1: + pstr_usac_config->ccfl = LEN_SUPERFRAME; + pstr_usac_config->in_frame_length = (LEN_SUPERFRAME * 4); + pstr_usac_config->sbr_enable = 1; + pstr_usac_config->drc_frame_size = (LEN_SUPERFRAME * 4); + break; + default: + pstr_usac_config->ccfl = LEN_SUPERFRAME; + pstr_usac_config->in_frame_length = LEN_SUPERFRAME; + pstr_usac_config->sbr_enable = 0; + pstr_usac_config->drc_frame_size = LEN_SUPERFRAME; + break; + } + if (pstr_input_config->ccfl_idx < NO_SBR_CCFL_768 || pstr_input_config->ccfl_idx > SBR_4_1) { + pstr_api_struct->config[0].ccfl_idx = NO_SBR_CCFL_1024; // default value + } else { + pstr_api_struct->config[0].ccfl_idx = pstr_input_config->ccfl_idx; + } + if (pstr_api_struct->config[0].ccfl_idx == SBR_8_3) { + pstr_api_struct->spectral_band_replication_tabs.ptr_sos_upsamp_tab = + (ixheaace_resampler_sos_table *)&iixheaace_resamp_1_to_3_filt_params; + + pstr_api_struct->spectral_band_replication_tabs.ptr_sos_downsamp_tab = + (ixheaace_resampler_sos_table *)&iixheaace_resamp_8_to_1_filt_params; + } else if (pstr_api_struct->config[0].ccfl_idx == SBR_2_1) { + pstr_api_struct->spectral_band_replication_tabs.ptr_resamp_tab = + (ixheaace_resampler_table *)&ixheaace_resamp_2_to_1_iir_filt_params; + } else if (pstr_api_struct->config[0].ccfl_idx == SBR_4_1) { + pstr_api_struct->spectral_band_replication_tabs.ptr_resamp_tab = + (ixheaace_resampler_table *)&ixheaace_resamp_4_to_1_iir_filt_params; + } + pstr_usac_config->use_drc_element = pstr_input_config->use_drc_element; + if (pstr_usac_config->use_drc_element) { + pstr_input_config->str_drc_cfg.str_uni_drc_config.str_channel_layout.base_ch_count = + pstr_input_config->i_channels; + pstr_input_config->str_drc_cfg.str_enc_params.sample_rate = pstr_input_config->i_samp_freq; + + pstr_input_config->str_drc_cfg.str_uni_drc_config.sample_rate = + pstr_input_config->str_drc_cfg.str_enc_params.sample_rate; + for (WORD32 i = 0; + i < pstr_input_config->str_drc_cfg.str_uni_drc_config.drc_coefficients_uni_drc_count; + i++) { + for (WORD32 j = 0; + j < pstr_input_config->str_drc_cfg.str_uni_drc_config.str_drc_coefficients_uni_drc[i] + .gain_set_count; + j++) { + pstr_input_config->str_drc_cfg.str_uni_drc_config.str_drc_coefficients_uni_drc[i] + .str_gain_set_params[j] + .delta_tmin = impd_drc_get_delta_t_min( + pstr_input_config->str_drc_cfg.str_uni_drc_config.sample_rate); + } + } + + pstr_usac_config->str_drc_cfg = pstr_input_config->str_drc_cfg; + pstr_usac_config->str_drc_cfg.str_enc_params.frame_size = pstr_usac_config->drc_frame_size; + pstr_usac_config->str_drc_cfg.str_uni_drc_config.str_drc_coefficients_uni_drc + ->drc_frame_size = pstr_usac_config->drc_frame_size; + pstr_input_config->drc_frame_size = pstr_usac_config->drc_frame_size; + } else { + pstr_usac_config->drc_frame_size = 0; + pstr_input_config->drc_frame_size = 0; + } } else { - if ((pstr_input_config->i_channels > MAX_NUM_CHANNELS)) { + if ((pstr_input_config->i_channels > MAX_NUM_CORE_CODER_CHANNELS)) { return (IA_EXHEAACE_CONFIG_FATAL_NUM_CHANNELS); } if (!((pstr_input_config->i_native_samp_freq == 7350) || @@ -830,7 +1127,126 @@ static VOID ixheaace_fill_mem_tabs(ixheaace_api_struct *pstr_api_struct, WORD32 ixheaace_mem_info_struct *pstr_mem_info; frame_length = pstr_api_struct->config[0].frame_length; WORD32 offset_size = 0; - { + if (pstr_api_struct->usac_en) { + WORD32 fac_downsample = 1; + if (pstr_api_struct->config[0].ccfl_idx > NO_SBR_CCFL_1024) { + fac_downsample = pstr_api_struct->config[0].ccfl_idx >> 1; + } else { + fac_downsample = 1; + } + /* persistant */ + { + pstr_mem_info = &pstr_api_struct->pstr_mem_info[IA_ENHAACPLUSENC_PERSIST_IDX]; + { + pstr_mem_info->ui_size = + sizeof(ixheaace_state_struct) + iusace_calc_pers_buf_sizes(pstr_api_struct); + if (pstr_api_struct->config[0].usac_config.sbr_enable) { + pstr_mem_info->ui_size += ixheaace_sbr_enc_pers_size( + 2, 0, pstr_api_struct->config[0].usac_config.sbr_harmonic); + } + pstr_mem_info->ui_size += 2 * + ia_enhaacplus_enc_sizeof_delay_buffer( + 0, AOT_USAC, pstr_api_struct->config[0].ccfl_idx, + sizeof(pstr_api_struct->pstr_state->inp_delay[0]), + pstr_api_struct->config[0].use_mps) * + pstr_api_struct->config[0].num_bs_elements; + + if (pstr_api_struct->config[0].use_mps) { + pstr_mem_info->ui_size += + (MAX_INPUT_SAMPLES) * sizeof(pstr_api_struct->pstr_state->time_signal_mps[0]); + + pstr_mem_info->ui_size += + (MAX_MPS_BS_PAYLOAD_SIZE) * sizeof(pstr_api_struct->pstr_state->mps_bs[0]); + + pstr_mem_info->ui_size += sizeof(ixheaace_mps_212_memory_struct) + 7; + } + if (1 == pstr_api_struct->config[0].usac_config.sbr_enable) { + pstr_mem_info->ui_size += + (MAX_FRAME_LEN * (1 << fac_downsample) + MAX_DS_8_1_FILTER_DELAY + INPUT_DELAY) * + MAX_CHANNELS * sizeof(pstr_mem_info->ui_size); + } + if ((2 != pstr_api_struct->config[0].usac_config.channels) && + (1 == pstr_api_struct->config[0].usac_config.sbr_enable)) { + pstr_mem_info->ui_size += + (MAX_INPUT_SAMPLES) * sizeof(pstr_api_struct->pstr_state->time_signal[0]); + } + } + + pstr_mem_info->ui_alignment = 8; + pstr_mem_info->ui_type = IA_MEMTYPE_PERSIST; + pstr_mem_info->ui_placement[0] = 0; + pstr_mem_info->ui_placement[1] = 0; + pstr_mem_info->ui_priority = IA_MEMPRIORITY_ANYWHERE; + pstr_mem_info->ui_placed[0] = 0; + pstr_mem_info->ui_placed[1] = 0; + } + + /* scratch */ + { + pstr_mem_info = &pstr_api_struct->pstr_mem_info[IA_ENHAACPLUSENC_SCRATCH_IDX]; + UWORD32 usac_scr_size = iusace_scratch_size(); + if (pstr_api_struct->config[0].usac_config.sbr_enable) { + UWORD32 sbr_scr_size = ixheaace_sbr_enc_scr_size() + ixheaace_resampler_scr_size(); + pstr_mem_info->ui_size = max(usac_scr_size, sbr_scr_size); + } else { + pstr_mem_info->ui_size = usac_scr_size; + } + + pstr_mem_info->ui_alignment = 8; + pstr_mem_info->ui_type = IA_MEMTYPE_SCRATCH; + pstr_mem_info->ui_placement[0] = 0; + pstr_mem_info->ui_placement[1] = 0; + pstr_mem_info->ui_priority = IA_MEMPRIORITY_ANYWHERE; + pstr_mem_info->ui_placed[0] = 0; + pstr_mem_info->ui_placed[1] = 0; + } + + /* input */ + { + pstr_mem_info = &pstr_api_struct->pstr_mem_info[IA_ENHAACPLUSENC_INPUT_IDX]; + WORD32 pcm_wd_sz; + num_channel = pstr_api_struct->config[0].i_channels; + pcm_wd_sz = pstr_api_struct->config[0].usac_config.ui_pcm_wd_sz; + pstr_mem_info->ui_size = frame_length * num_channel * (pcm_wd_sz >> 3); + if (1 == pstr_api_struct->config[0].usac_config.sbr_enable) { + switch (pstr_api_struct->config[0].ccfl_idx) { + case SBR_8_3: // 8:3 + pstr_mem_info->ui_size *= 8; + pstr_mem_info->ui_size /= 3; + break; + + case SBR_2_1: // 2:1 + pstr_mem_info->ui_size *= 2; + break; + + case SBR_4_1: // 4:1 + pstr_mem_info->ui_size *= 4; + break; + } + } + + pstr_mem_info->ui_alignment = 8; /* As input is used as scratch memory internally */ + pstr_mem_info->ui_type = IA_MEMTYPE_INPUT; + pstr_mem_info->ui_placement[0] = 0; + pstr_mem_info->ui_placement[1] = 0; + pstr_mem_info->ui_priority = IA_MEMPRIORITY_ANYWHERE; + pstr_mem_info->ui_placed[0] = 0; + pstr_mem_info->ui_placed[1] = 0; + } + + /* output */ + { + pstr_mem_info = &pstr_api_struct->pstr_mem_info[IA_ENHAACPLUSENC_OUTPUT_IDX]; + pstr_mem_info->ui_size = pstr_api_struct->pstr_mem_info[IA_ENHAACPLUSENC_INPUT_IDX].ui_size; + pstr_mem_info->ui_alignment = 8; + pstr_mem_info->ui_type = IA_MEMTYPE_OUTPUT; + pstr_mem_info->ui_placement[0] = 0; + pstr_mem_info->ui_placement[1] = 0; + pstr_mem_info->ui_priority = IA_MEMPRIORITY_ANYWHERE; + pstr_mem_info->ui_placed[0] = 0; + pstr_mem_info->ui_placed[1] = 0; + } + } else { /* persistant */ { pstr_mem_info = &pstr_api_struct->pstr_mem_info[IA_ENHAACPLUSENC_PERSIST_IDX]; @@ -847,7 +1263,7 @@ static VOID ixheaace_fill_mem_tabs(ixheaace_api_struct *pstr_api_struct, WORD32 if (pstr_api_struct->config[0].aot != AOT_AAC_LC && pstr_api_struct->config[0].aot != AOT_AAC_LD) { pstr_mem_info->ui_size += ixheaace_sbr_enc_pers_size( - num_channel, pstr_api_struct->config[0].use_parametric_stereo); + num_channel, pstr_api_struct->config[0].use_parametric_stereo, 0); } offset_size = ia_enhaacplus_enc_sizeof_delay_buffer( pstr_api_struct->config[0].aac_config.flag_framelength_small, aot, 3, @@ -867,8 +1283,8 @@ static VOID ixheaace_fill_mem_tabs(ixheaace_api_struct *pstr_api_struct, WORD32 for (ele_idx = 0; ele_idx < pstr_api_struct->config[0].num_bs_elements; ele_idx++) { num_channel = pstr_api_struct->config[ele_idx].i_channels; if (pstr_api_struct->config[ele_idx].element_type != ID_LFE) - pstr_mem_info->ui_size += ixheaace_sbr_enc_pers_size(num_channel, 0); - pstr_mem_info->ui_size += ia_enhaacplus_enc_aac_enc_pers_size(num_channel, aot); + pstr_mem_info->ui_size += ixheaace_sbr_enc_pers_size(num_channel, 0, 0); + pstr_mem_info->ui_size += ia_enhaacplus_enc_aac_enc_pers_size(num_channel, aot) + 32; } } @@ -1028,8 +1444,135 @@ static IA_ERRORCODE ixheaace_alloc_and_assign_mem(ixheaace_api_struct *pstr_api_ /* Set persistent memory pointer in api obj */ pstr_api_struct->pstr_state = (ixheaace_state_struct *)pv_value; + WORD32 i, inp_delay_size; + WORD8 *p_temp; + if (pstr_api_struct->usac_en) { + memset(pstr_api_struct->pstr_state, 0, sizeof(*(pstr_api_struct->pstr_state))); + ia_usac_encoder_config_struct *pstr_usac_config = &pstr_api_struct->config[0].usac_config; + ixheaace_state_struct *pstr_state = pstr_api_struct->pstr_state; + ia_usac_data_struct *pstr_usac_enc_data = &(pstr_state->str_usac_enc_data); - { + pstr_state->ptr_in_buf = (FLOAT32 **)((WORD8 *)pstr_state + offset_size); + + p_offset = + (WORD8 *)pstr_state->ptr_in_buf + (pstr_usac_config->channels * sizeof(FLOAT32 *)); + + // Input delay + pstr_state->inp_delay = (FLOAT32 *)(p_offset); + inp_delay_size = + 2 * + ia_enhaacplus_enc_sizeof_delay_buffer( + 0, AOT_USAC, pstr_api_struct->config[0].ccfl_idx, + sizeof(pstr_state->inp_delay[0]), pstr_api_struct->config[0].use_mps) * + pstr_api_struct->config[0].num_bs_elements; + memset(pstr_state->inp_delay, 0, inp_delay_size); + p_offset += inp_delay_size; + p_offset = IXHEAACE_ALIGN_MEMORY((SIZE_T)p_offset, 8); + if (1 == pstr_usac_config->sbr_enable) { + if (2 != pstr_usac_config->channels) { + pstr_api_struct->pstr_state->time_signal = (FLOAT32 *)(p_offset); + + memset(pstr_api_struct->pstr_state->time_signal, 0, + (MAX_INPUT_SAMPLES) * sizeof(pstr_api_struct->pstr_state->time_signal[0])); + p_offset += (MAX_INPUT_SAMPLES) * sizeof(pstr_api_struct->pstr_state->time_signal[0]); + p_offset = IXHEAACE_ALIGN_MEMORY((SIZE_T)p_offset, 8); + } + + pstr_api_struct->pstr_state->spectral_band_replication_enc_pers_mem[0] = + (struct ixheaace_str_sbr_enc *)p_offset; + p_offset = p_offset + ixheaace_sbr_enc_pers_size(pstr_usac_config->channels, 0, + pstr_usac_config->sbr_harmonic); + + p_offset = IXHEAACE_ALIGN_MEMORY((SIZE_T)p_offset, 8); + } + if (1 == pstr_api_struct->config[0].use_mps) { + pstr_api_struct->pstr_state->time_signal_mps = (FLOAT32 *)(p_offset); + + memset(pstr_api_struct->pstr_state->time_signal_mps, 0, + (MAX_INPUT_SAMPLES) * sizeof(pstr_api_struct->pstr_state->time_signal_mps[0])); + p_offset = IXHEAACE_ALIGN_MEMORY((SIZE_T)p_offset, 8); + p_offset += + (MAX_INPUT_SAMPLES) * sizeof(pstr_api_struct->pstr_state->time_signal_mps[0]); + + pstr_api_struct->pstr_state->mps_bs = (UWORD8 *)(p_offset); + + memset(pstr_api_struct->pstr_state->mps_bs, 0, + (MAX_MPS_BS_PAYLOAD_SIZE) * sizeof(pstr_api_struct->pstr_state->mps_bs[0])); + p_offset = IXHEAACE_ALIGN_MEMORY((SIZE_T)p_offset, 8); + + p_offset += (MAX_MPS_BS_PAYLOAD_SIZE) * sizeof(pstr_api_struct->pstr_state->mps_bs[0]); + p_offset = IXHEAACE_ALIGN_MEMORY((SIZE_T)p_offset, 8); + + pstr_api_struct->pstr_state->mps_pers_mem = (ixheaace_mps_212_memory_struct *)p_offset; + p_offset += sizeof(ixheaace_mps_212_memory_struct); + + p_offset = IXHEAACE_ALIGN_MEMORY((SIZE_T)p_offset, 8); + } else { + pstr_api_struct->pstr_state->mps_bs = NULL; + } + if (1 == pstr_usac_config->use_drc_element) { + pstr_state->pp_drc_in_buf = (FLOAT32 **)((WORD8 *)p_offset); + p_offset += pstr_usac_config->channels * sizeof(pstr_state->pp_drc_in_buf[0]); + p_temp = p_offset; + p_offset = IXHEAACE_ALIGN_MEMORY((SIZE_T)p_offset, 8); + for (i = 0; i < pstr_usac_config->channels; i++) { + pstr_state->pp_drc_in_buf[i] = (FLOAT32 *)p_offset; + p_offset += + pstr_usac_config->drc_frame_size * sizeof(pstr_state->pp_drc_in_buf[0][0]) * 2; + } + p_offset = IXHEAACE_ALIGN_MEMORY((SIZE_T)p_offset, 8); + memset(p_temp, 0, (p_offset - p_temp)); + } + p_temp = p_offset; + + for (i = 0; i < pstr_usac_config->channels; i++) { + pstr_state->ptr_in_buf[i] = (FLOAT32 *)p_offset; + p_offset += pstr_usac_config->ccfl * sizeof(FLOAT32) * 2; + } + p_offset = IXHEAACE_ALIGN_MEMORY((SIZE_T)p_offset, 8); + memset(p_temp, 0, (p_offset - p_temp)); + + p_temp = p_offset; + for (i = 0; i < pstr_usac_config->channels; i++) { + pstr_usac_enc_data->ptr_time_data[i] = (FLOAT64 *)p_offset; + p_offset += 2 * (pstr_usac_config->ccfl) * sizeof(FLOAT64); + } + p_offset = IXHEAACE_ALIGN_MEMORY((SIZE_T)p_offset, 8); + for (i = 0; i < pstr_usac_config->channels; i++) { + pstr_usac_enc_data->ptr_look_ahead_time_data[i] = (FLOAT64 *)p_offset; + p_offset += pstr_usac_config->ccfl * sizeof(FLOAT64); + } + p_offset = IXHEAACE_ALIGN_MEMORY((SIZE_T)p_offset, 8); + for (i = 0; i < pstr_usac_config->channels; i++) { + pstr_usac_enc_data->spectral_line_vector[i] = (FLOAT64 *)p_offset; + p_offset += 2 * pstr_usac_config->ccfl * sizeof(FLOAT64); + } + p_offset = IXHEAACE_ALIGN_MEMORY((SIZE_T)p_offset, 8); + for (i = 0; i < pstr_usac_config->channels; i++) { + pstr_usac_enc_data->ptr_2frame_time_data[i] = (FLOAT64 *)p_offset; + p_offset += 3 * pstr_usac_config->ccfl * sizeof(FLOAT64); + } + p_offset = IXHEAACE_ALIGN_MEMORY((SIZE_T)p_offset, 8); + memset(p_temp, 0, p_offset - p_temp); + + if (pstr_usac_config->tns_select != 0) { + p_temp = p_offset; + for (i = 0; i < pstr_usac_config->channels; i++) { + pstr_usac_enc_data->pstr_tns_info[i] = (ia_tns_info *)p_offset; + p_offset += sizeof(ia_tns_info); + } + p_offset = IXHEAACE_ALIGN_MEMORY((SIZE_T)p_offset, 8); + memset(p_temp, 0, p_offset - p_temp); + } + + p_temp = p_offset; + p_offset = IXHEAACE_ALIGN_MEMORY((SIZE_T)p_offset, 8); + for (i = 0; i < pstr_usac_config->channels; i++) { + pstr_usac_enc_data->td_encoder[i] = (ia_usac_td_encoder_struct *)p_offset; + p_offset += sizeof(ia_usac_td_encoder_struct); + } + memset(p_temp, 0, p_offset - p_temp); + } else { WORD32 num_aac_chan; ixheaace_state_struct *pstr_state = pstr_api_struct->pstr_state; memset(pstr_api_struct->pstr_state, 0, sizeof(*(pstr_api_struct->pstr_state))); @@ -1097,15 +1640,24 @@ static IA_ERRORCODE ixheaace_alloc_and_assign_mem(ixheaace_api_struct *pstr_api_ /* Set spectral_band_replication_ enc persistent memory pointer in api obj */ pstr_api_struct->pstr_state->spectral_band_replication_enc_pers_mem[ele_idx] = (struct ixheaace_str_sbr_enc *)p_offset; - p_offset = p_offset + ixheaace_sbr_enc_pers_size( - num_aac_chan, - pstr_api_struct->config[ele_idx].use_parametric_stereo); + + p_offset = + p_offset + + ixheaace_sbr_enc_pers_size( + num_aac_chan, pstr_api_struct->config[ele_idx].use_parametric_stereo, 0); + p_offset = IXHEAACE_ALIGN_MEMORY((SIZE_T)p_offset, 8); } } } } } + if ((i_idx == IA_MEMTYPE_SCRATCH) && pstr_api_struct->usac_en) { + pstr_api_struct->pstr_state->str_usac_enc_data.str_scratch.ptr_scratch_buf = + (UWORD8 *)pstr_api_struct->pp_mem[IA_MEMTYPE_SCRATCH]; + memset(pstr_api_struct->pp_mem[IA_MEMTYPE_SCRATCH], 0, + pstr_api_struct->pstr_mem_info[i_idx].ui_size); + } if (i_idx == IA_ENHAACPLUSENC_INPUT_IDX) { ptr_out_cfg->ui_inp_buf_size = ptr_out_cfg->mem_info_table[i_idx].ui_size; } @@ -1113,6 +1665,288 @@ static IA_ERRORCODE ixheaace_alloc_and_assign_mem(ixheaace_api_struct *pstr_api_ } return err_code; } +static IA_ERRORCODE ia_usac_enc_init(ixheaace_api_struct *pstr_api_struct, WORD32 ccfl_idx) { + IA_ERRORCODE error = IA_NO_ERROR; + WORD32 i = 0; + ixheaace_config_struct *pstr_config = &pstr_api_struct->config[0]; + ixheaace_state_struct *pstr_enc_state = pstr_api_struct->pstr_state; + ia_usac_data_struct *pstr_enc_data = &pstr_enc_state->str_usac_enc_data; + ia_usac_encoder_config_struct *pstr_usac_config = &pstr_config->usac_config; + + pstr_usac_config->bit_rate = pstr_api_struct->config[0].aac_config.bit_rate; + + if ((pstr_usac_config->codec_mode == USAC_SWITCHED) || + (pstr_usac_config->codec_mode == USAC_ONLY_FD)) { + pstr_usac_config->aac_allow_scalefacs = 1; + if (pstr_usac_config->aac_scale_facs == 0) pstr_usac_config->aac_allow_scalefacs = 0; + } + + if (pstr_usac_config->codec_mode == USAC_ONLY_TD) { + for (i = 0; i < pstr_config->i_channels; i++) { + pstr_enc_data->core_mode_prev[i] = CORE_MODE_FD; + pstr_enc_data->core_mode[i] = CORE_MODE_TD; + } + } else { + for (i = 0; i < pstr_config->i_channels; i++) { + pstr_enc_data->core_mode_prev[i] = CORE_MODE_FD; + pstr_enc_data->core_mode[i] = CORE_MODE_FD; + } + } + + if (1 == pstr_usac_config->use_drc_element) { + pstr_enc_data->str_scratch.drc_scratch = pstr_enc_data->str_scratch.ptr_scratch_buf; + } + if (pstr_usac_config->sbr_enable) { + WORD8 *sbr_scr_ptr = (WORD8 *)pstr_enc_data->str_scratch.ptr_scratch_buf; + ixheaace_audio_specific_config_struct *pstr_asc = &pstr_enc_state->audio_specific_config; + ixheaace_str_sbr_cfg spectral_band_replication_config; + // SBR defaults + iaace_config *pstr_sbr_config = &(pstr_api_struct->config[0].aac_config); + WORD32 sbr_ratio = 0; + WORD32 samples = pstr_usac_config->ccfl; + // Set scratch buffers for SBR and resampler + pstr_api_struct->pstr_state->temp_buff_sbr = + (WORD8 *)pstr_enc_data->str_scratch.ptr_scratch_buf; + pstr_api_struct->pstr_state->ptr_temp_buff_resamp = + (WORD8 *)pstr_enc_data->str_scratch.ptr_scratch_buf + ixheaace_sbr_enc_scr_size(); + + ixheaace_initialize_sbr_defaults(&spectral_band_replication_config); + // Set SBR codec as USAC + spectral_band_replication_config.sbr_codec = USAC_SBR; + spectral_band_replication_config.sbr_pvc_active = pstr_usac_config->sbr_pvc_active; + spectral_band_replication_config.sbr_harmonic = pstr_usac_config->sbr_harmonic; + spectral_band_replication_config.hq_esbr = pstr_usac_config->hq_esbr; + pstr_usac_config->core_sample_rate = pstr_usac_config->sample_rate / 2; + switch (pstr_usac_config->ccfl_idx) { + case SBR_4_1: + spectral_band_replication_config.sbr_ratio_idx = USAC_SBR_RATIO_INDEX_4_1; + spectral_band_replication_config.sbr_pvc_rate = USAC_SBR_DOWNSAMPLE_RATIO_4_1; + pstr_usac_config->core_sample_rate = pstr_usac_config->sample_rate / 4; + sbr_ratio = 4; + samples *= 4; + break; + case SBR_8_3: + spectral_band_replication_config.sbr_ratio_idx = USAC_SBR_RATIO_INDEX_8_3; + spectral_band_replication_config.sbr_pvc_rate = USAC_SBR_DOWNSAMPLE_RATIO_2_1; + sbr_ratio = 2; + samples *= 8; + samples /= 3; + break; + case SBR_2_1: + spectral_band_replication_config.sbr_ratio_idx = USAC_SBR_RATIO_INDEX_2_1; + spectral_band_replication_config.sbr_pvc_rate = USAC_SBR_DOWNSAMPLE_RATIO_2_1; + sbr_ratio = 2; + samples *= 2; + break; + default: + spectral_band_replication_config.sbr_ratio_idx = USAC_SBR_RATIO_NO_SBR; + spectral_band_replication_config.sbr_pvc_rate = 2; + sbr_ratio = 2; + break; + } + if (pstr_api_struct->pstr_state->mps_enable) { + ixheaace_mps_212_memory_struct *pstr_mps_memory; + pstr_mps_memory = pstr_api_struct->pstr_state->mps_pers_mem; + ixheaace_mps_212_open(&pstr_api_struct->pstr_mps_212_enc, pstr_mps_memory); + pstr_asc->str_aac_config.num_sac_cfg_bits = 0; + + error = ixheaace_mps_212_initialise( + pstr_api_struct->pstr_mps_212_enc, AOT_USAC, pstr_usac_config->sample_rate, + &pstr_sbr_config->bit_rate, sbr_ratio, (WORD32)samples, samples, 515 * sbr_ratio, + (WORD8 *)pstr_api_struct->pstr_state->ptr_temp_buff_resamp); + if (error) { + return error; + } + + pstr_asc->str_aac_config.num_sac_cfg_bits = ixheaace_mps_212_get_spatial_specific_config( + pstr_api_struct->pstr_mps_212_enc, (WORD8 *)pstr_asc->str_aac_config.sac_cfg_data, + sizeof(pstr_asc->str_aac_config.sac_cfg_data), AOT_USAC); + } + ixheaace_adjust_sbr_settings( + &spectral_band_replication_config, pstr_sbr_config->bit_rate, + (pstr_api_struct->pstr_state->mps_enable != 1) ? pstr_config->i_channels : 1, + pstr_usac_config->core_sample_rate, AACENC_TRANS_FAC, 24000, + pstr_api_struct->spectral_band_replication_tabs.ptr_qmf_tab, + pstr_api_struct->pstr_state->aot); + + error = ixheaace_env_open( + &pstr_api_struct->pstr_state->spectral_band_replication_enc_pers_mem[0], + &spectral_band_replication_config, &pstr_sbr_config->band_width, sbr_scr_ptr, + &(pstr_api_struct->spectral_band_replication_tabs), &pstr_asc->str_aac_config.sbr_config); + if (error) { + return error; + } + + if (pstr_api_struct->config[0].ccfl_idx >= 2) { + pstr_api_struct->pstr_state->downsample[0] = 1; + } else { + pstr_api_struct->pstr_state->downsample[0] = 0; + } + + if (pstr_api_struct->pstr_state->downsample[0]) { + IA_ERRORCODE resamp_error = IA_NO_ERROR; + WORD32 resamp_ratio = 0, upsamp_fac = 0, downsamp_fac = 0; + WORD32 ele_idx = 0, ch_idx = 0; + + if (pstr_api_struct->config[0].ccfl_idx == SBR_8_3) { + upsamp_fac = 3; + downsamp_fac = 8; + pstr_usac_config->sample_rate /= 2; + } else if (pstr_api_struct->config[0].ccfl_idx == SBR_2_1) { + resamp_ratio = 2; + pstr_usac_config->sample_rate /= 2; + } else if (pstr_api_struct->config[0].ccfl_idx == SBR_4_1) { + resamp_ratio = 4; + pstr_usac_config->sample_rate /= 4; + } + + if (pstr_api_struct->config[0].ccfl_idx == SBR_8_3) { + if (upsamp_fac != 3 || downsamp_fac != 8) { + return IA_EXHEAACE_CONFIG_FATAL_USAC_RESAMPLER_RATIO; + } + } else { + if (resamp_ratio != 2 && resamp_ratio != 4) { + return IA_EXHEAACE_CONFIG_FATAL_USAC_RESAMPLER_RATIO; + } + } + if (pstr_api_struct->config[0].ccfl_idx == SBR_8_3) { // Upsampler initialization + resamp_error = ia_enhaacplus_enc_init_iir_sos_resampler( + &(pstr_api_struct->pstr_state->up_sampler[ele_idx][ch_idx]), upsamp_fac, + pstr_api_struct->spectral_band_replication_tabs.ptr_sos_upsamp_tab); + if (resamp_error) { + return resamp_error; + } + if (pstr_api_struct->config[0].i_channels > 1) { + resamp_error = ia_enhaacplus_enc_init_iir_sos_resampler( + &(pstr_api_struct->pstr_state->up_sampler[ele_idx][ch_idx + 1]), upsamp_fac, + pstr_api_struct->spectral_band_replication_tabs.ptr_sos_upsamp_tab); + if (resamp_error) { + return resamp_error; + } + } + if (pstr_usac_config->sbr_harmonic) { + resamp_error = ia_enhaacplus_enc_init_iir_sos_resampler( + &(pstr_api_struct->pstr_state->hbe_up_sampler[ele_idx][ch_idx]), upsamp_fac, + pstr_api_struct->spectral_band_replication_tabs.ptr_sos_upsamp_tab); + if (resamp_error) { + return resamp_error; + } + if (pstr_api_struct->config[0].i_channels > 1) { + resamp_error = ia_enhaacplus_enc_init_iir_sos_resampler( + &(pstr_api_struct->pstr_state->hbe_up_sampler[ele_idx][ch_idx + 1]), upsamp_fac, + pstr_api_struct->spectral_band_replication_tabs.ptr_sos_upsamp_tab); + if (resamp_error) { + return resamp_error; + } + } + } + // Downsampler initialization + resamp_error = ia_enhaacplus_enc_init_iir_sos_resampler( + &(pstr_api_struct->pstr_state->down_samp_sos[ele_idx][ch_idx]), downsamp_fac, + pstr_api_struct->spectral_band_replication_tabs.ptr_sos_downsamp_tab); + if (resamp_error) { + return resamp_error; + } + if (pstr_api_struct->config[0].i_channels > 1) { + resamp_error = ia_enhaacplus_enc_init_iir_sos_resampler( + &(pstr_api_struct->pstr_state->down_samp_sos[ele_idx][ch_idx + 1]), downsamp_fac, + pstr_api_struct->spectral_band_replication_tabs.ptr_sos_downsamp_tab); + if (resamp_error) { + return resamp_error; + } + } + if (pstr_usac_config->sbr_harmonic) { + resamp_error = ia_enhaacplus_enc_init_iir_sos_resampler( + &(pstr_api_struct->pstr_state->hbe_down_samp_sos[ele_idx][ch_idx]), downsamp_fac, + pstr_api_struct->spectral_band_replication_tabs.ptr_sos_downsamp_tab); + if (resamp_error) { + return resamp_error; + } + if (pstr_api_struct->config[0].i_channels > 1) { + resamp_error = ia_enhaacplus_enc_init_iir_sos_resampler( + &(pstr_api_struct->pstr_state->hbe_down_samp_sos[ele_idx][ch_idx + 1]), + downsamp_fac, + pstr_api_struct->spectral_band_replication_tabs.ptr_sos_downsamp_tab); + if (resamp_error) { + return resamp_error; + } + } + } + } else if (pstr_api_struct->config[0].ccfl_idx == SBR_2_1 || + pstr_api_struct->config[0].ccfl_idx == SBR_4_1) { + resamp_error = ia_enhaacplus_enc_init_iir_resampler( + &(pstr_api_struct->pstr_state->down_sampler[ele_idx][ch_idx]), resamp_ratio, + pstr_api_struct->spectral_band_replication_tabs.ptr_resamp_tab); + if (resamp_error) { + return resamp_error; + } + if (pstr_api_struct->config[0].i_channels > 1) { + resamp_error = ia_enhaacplus_enc_init_iir_resampler( + &(pstr_api_struct->pstr_state->down_sampler[ele_idx][ch_idx + 1]), resamp_ratio, + pstr_api_struct->spectral_band_replication_tabs.ptr_resamp_tab); + if (resamp_error) { + return resamp_error; + } + } + if (pstr_usac_config->sbr_harmonic) { + resamp_error = ia_enhaacplus_enc_init_iir_resampler( + &(pstr_api_struct->pstr_state->hbe_down_sampler[ele_idx][ch_idx]), resamp_ratio, + pstr_api_struct->spectral_band_replication_tabs.ptr_resamp_tab); + if (resamp_error) { + return resamp_error; + } + if (pstr_api_struct->config[0].i_channels > 1) { + resamp_error = ia_enhaacplus_enc_init_iir_resampler( + &(pstr_api_struct->pstr_state->hbe_down_sampler[ele_idx][ch_idx + 1]), + resamp_ratio, pstr_api_struct->spectral_band_replication_tabs.ptr_resamp_tab); + if (resamp_error) { + return resamp_error; + } + } + } + } + } + } + + error = iusace_enc_init(pstr_usac_config, &pstr_api_struct->pstr_state->audio_specific_config, + &pstr_api_struct->pstr_state->str_usac_enc_data); + if (error) { + return error; + } + + ia_bit_buf_struct *pstr_ia_asc_bit_buf; + pstr_ia_asc_bit_buf = iusace_create_bit_buffer( + &(pstr_api_struct->pstr_state->str_bit_buf), pstr_api_struct->pp_mem[IA_MEMTYPE_OUTPUT], + pstr_api_struct->pstr_mem_info[IA_MEMTYPE_OUTPUT].ui_size, 1); +#ifdef ENABLE_SET_JUMP + pstr_ia_asc_bit_buf->iusace_jmp_buf = &api_init_jmp_buf; +#endif + if (pstr_usac_config->sbr_enable) { + pstr_api_struct->pstr_state->audio_specific_config.str_usac_config.str_usac_element_config + ->stereo_config_index = (pstr_api_struct->pstr_state->mps_enable == 1) ? 2 : 0; + pstr_api_struct->pstr_state->audio_specific_config.str_usac_config.str_usac_element_config + ->str_usac_sbr_config.bs_inter_tes = pstr_usac_config->sbr_inter_tes_active; + pstr_api_struct->pstr_state->audio_specific_config.str_usac_config.str_usac_element_config + ->str_usac_sbr_config.bs_pvc = pstr_usac_config->sbr_pvc_active; + pstr_api_struct->pstr_state->audio_specific_config.str_usac_config.str_usac_element_config + ->str_usac_sbr_config.dflt_header_extra1 = 0; + pstr_api_struct->pstr_state->audio_specific_config.str_usac_config.str_usac_element_config + ->str_usac_sbr_config.dflt_header_extra2 = 0; + pstr_api_struct->pstr_state->audio_specific_config.str_usac_config.str_usac_element_config + ->str_usac_sbr_config.dflt_start_freq = 0; + pstr_api_struct->pstr_state->audio_specific_config.str_usac_config.str_usac_element_config + ->str_usac_sbr_config.dflt_stop_freq = 4; + pstr_api_struct->pstr_state->audio_specific_config.str_usac_config.str_usac_element_config + ->str_usac_sbr_config.harmonic_sbr = pstr_usac_config->sbr_harmonic; + } + + ixheaace_get_audiospecific_config_bytes(pstr_ia_asc_bit_buf, + &pstr_api_struct->pstr_state->audio_specific_config, + AOT_USAC, ccfl_idx); + pstr_api_struct->pstr_state->i_out_bytes = (pstr_ia_asc_bit_buf->cnt_bits + 7) >> 3; + + return IA_NO_ERROR; +} static IA_ERRORCODE ia_enhaacplus_enc_init(ixheaace_api_struct *pstr_api_struct, WORD32 ele_idx) { IA_ERRORCODE error = IA_NO_ERROR; @@ -1824,7 +2658,7 @@ static IA_ERRORCODE ia_enhaacplus_enc_execute(ixheaace_api_struct *pstr_api_stru pstr_api_struct->pstr_state->anc_data_bytes[ele_idx], &(pstr_api_struct->spectral_band_replication_tabs), &(pstr_api_struct->common_tabs), &(mps_extension_payload.p_data[0]), mps_extension_payload.data_size, - pstr_api_struct->config[0].aac_config.flag_framelength_small); + pstr_api_struct->config[0].aac_config.flag_framelength_small, NULL); if (error != IA_NO_ERROR) { return error; @@ -1873,11 +2707,9 @@ static IA_ERRORCODE ia_enhaacplus_enc_execute(ixheaace_api_struct *pstr_api_stru if (pstr_api_struct->config->adts_flag) { pub_out_buf = ((pUWORD8)pstr_api_struct->pp_mem[IA_ENHAACPLUSENC_OUTPUT_IDX]); { - WORD32 bit_rate = 0; WORD32 num_channels = 0; for (ele = 0; ele < pstr_api_struct->config[0].num_bs_elements; ele++) { - bit_rate += pstr_api_struct->config[ele].aac_config.bit_rate; num_channels += pstr_api_struct->config[ele].i_channels; } { @@ -1895,7 +2727,555 @@ static IA_ERRORCODE ia_enhaacplus_enc_execute(ixheaace_api_struct *pstr_api_stru return IA_NO_ERROR; } +static IA_ERRORCODE iusace_process(ixheaace_api_struct *pstr_api_struct) { + IA_ERRORCODE error = IA_NO_ERROR; + WORD32 idx; +#ifdef ENABLE_SET_JUMP + jmp_buf api_execute_jmp_buf; + error = setjmp(api_execute_jmp_buf); + if (error != IA_NO_ERROR) { + return IA_EXHEAACE_EXE_NONFATAL_USAC_INSUFFICIENT_WRITE_BUFFER_SIZE; + } +#endif // ENABLE_SET_JUMP + WORD32 write_off_set = 0; + WORD32 core_coder_frame_length; + WORD32 usac_independency_flg; + UWORD32 padding_bits = 0; + WORD32 core_sample; + WORD32 drc_sample; + WORD32 i4_inp_data; + WORD32 ptr_inp_buf_offset = 0; + WORD32 num_ch; + WORD16 *ps_inp_buf = NULL; + WORD8 *pi1_inp_buf = NULL; + WORD8 *ps_out_buf = NULL; + WORD32 *pi4_inp_buf = NULL; + FLOAT32 *ptr_input_buffer = NULL; + FLOAT32 *ptr_inp_buf[MAX_TIME_CHANNELS]; + FLOAT32 *ptr_drc_inp_buf[MAX_TIME_CHANNELS]; + ixheaace_state_struct *pstr_state = pstr_api_struct->pstr_state; + ia_bit_buf_struct *pstr_it_bit_buff = &pstr_state->str_bit_buf; + ia_usac_encoder_config_struct *pstr_config = &pstr_api_struct->config[0].usac_config; + ia_usac_data_struct *pstr_usac_data = &pstr_api_struct->pstr_state->str_usac_enc_data; + iusace_scratch_mem *pstr_scratch = &pstr_usac_data->str_scratch; + ia_classification_struct *pstr_sig_class_data = + &pstr_state->str_usac_enc_data.str_sig_class_data; + core_sample = (pstr_config->ccfl * pstr_config->channels); + drc_sample = pstr_config->drc_frame_size * pstr_config->channels; + core_coder_frame_length = pstr_config->ccfl; + num_ch = pstr_config->channels; + usac_independency_flg = !(pstr_usac_data->usac_independency_flag_count % + pstr_usac_data->usac_independency_flag_interval); + pstr_usac_data->usac_independency_flag = usac_independency_flg; + ps_inp_buf = (WORD16 *)pstr_api_struct->pp_mem[IA_MEMTYPE_INPUT]; + pi1_inp_buf = (WORD8 *)pstr_api_struct->pp_mem[IA_MEMTYPE_INPUT]; + ps_out_buf = (WORD8 *)pstr_api_struct->pp_mem[IA_MEMTYPE_OUTPUT]; + + if (pstr_config->use_drc_element) { + for (idx = 0; idx < core_sample; idx++) { + pstr_api_struct->pstr_state->pp_drc_in_buf[idx % num_ch][idx / num_ch] = + pstr_api_struct->pstr_state + ->pp_drc_in_buf[idx % num_ch][idx / num_ch + pstr_config->drc_frame_size]; + } + ptr_inp_buf_offset = pstr_config->drc_frame_size; + for (idx = 0; idx < num_ch; idx++) { + ptr_drc_inp_buf[idx] = pstr_api_struct->pstr_state->pp_drc_in_buf[idx]; + } + } + + ixheaace_pstr_sbr_enc pstr_sbr_encoder = + pstr_api_struct->pstr_state->spectral_band_replication_enc_pers_mem[0]; + if (pstr_config->sbr_enable) { + ixheaace_mps_enc_ext_payload mps_extension_payload; + UWORD8 *mps_bs = pstr_api_struct->pstr_state->mps_bs; + FLOAT32 *time_signal_mps = pstr_api_struct->pstr_state->time_signal_mps; + WORD32 sbr_pvc_mode = 0; + WORD32 sbr_patching_mode = 1; + WORD32 ccfl_size; + WORD32 num_samples_read; + WORD32 out_samples, ch; + WORD32 resamp_ratio = + ia_enhaacplus_enc_compute_resampling_ratio(pstr_api_struct->config[0].ccfl_idx); + switch (pstr_config->codec_mode) { + case USAC_SWITCHED: + if (pstr_usac_data->str_sig_class_data.coding_mode == 2) { + sbr_pvc_mode = 0; + } else { + sbr_pvc_mode = 2; + } + sbr_patching_mode = 1; + break; + case USAC_ONLY_FD: + sbr_pvc_mode = 0; + sbr_patching_mode = 0; + break; + case USAC_ONLY_TD: + sbr_pvc_mode = 2; + sbr_patching_mode = 1; + break; + } + + write_off_set = INPUT_DELAY_LC * IXHEAACE_MAX_CH_IN_BS_ELE; + if (pstr_api_struct->pstr_state->downsample[0]) { + if (pstr_api_struct->config[0].ccfl_idx == SBR_8_3) { + write_off_set += + (pstr_api_struct->pstr_state->down_samp_sos[0][0].delay) * IXHEAACE_MAX_CH_IN_BS_ELE; + + write_off_set += + (pstr_api_struct->pstr_state->up_sampler[0][0].delay) * IXHEAACE_MAX_CH_IN_BS_ELE; + } else if (pstr_api_struct->config[0].ccfl_idx == SBR_2_1 || + pstr_api_struct->config[0].ccfl_idx == SBR_4_1) { + write_off_set += + (pstr_api_struct->pstr_state->down_sampler[0][0].delay) * IXHEAACE_MAX_CH_IN_BS_ELE; + } + } + + ptr_input_buffer = pstr_api_struct->pstr_state->inp_delay; + ccfl_size = pstr_api_struct->config[0].usac_config.ccfl; + num_samples_read = ccfl_size * pstr_api_struct->config[0].i_channels; + switch (pstr_api_struct->config[0].ccfl_idx) { + case SBR_8_3: + num_samples_read *= 8; + num_samples_read /= 3; + break; + + case SBR_2_1: + num_samples_read *= 2; + break; + + case SBR_4_1: + num_samples_read *= 4; + break; + } + + mps_extension_payload.p_data = mps_bs; + memset(&mps_extension_payload, 0, sizeof(ixheaace_mps_enc_ext_payload)); + + if ((pstr_api_struct->pstr_mps_212_enc != NULL) && pstr_api_struct->pstr_state->mps_enable) { + for (idx = 0; idx < num_samples_read / 2; idx++) { + time_signal_mps[idx] = (FLOAT32)ps_inp_buf[2 * idx]; + time_signal_mps[num_samples_read / 2 + idx] = (FLOAT32)ps_inp_buf[2 * idx + 1]; + } + error = ixheaace_mps_212_process(pstr_api_struct->pstr_mps_212_enc, time_signal_mps, + num_samples_read, &mps_extension_payload); + if (error) { + return error; + } + if (pstr_api_struct->pstr_state->mps_enable == 1) { + for (idx = 0; idx < num_samples_read / 2; idx++) { + ptr_input_buffer[write_off_set + 2 * idx] = time_signal_mps[idx]; + ptr_input_buffer[write_off_set + 2 * idx + 1] = + time_signal_mps[num_samples_read / 2 + idx]; + } + } + } else if (pstr_api_struct->config[0].i_channels == 2 && + pstr_api_struct->config[0].chmode_nchannels == 2) { + for (idx = 0; idx < (num_samples_read); idx++) { + ptr_input_buffer[write_off_set + idx] = (FLOAT32)ps_inp_buf[idx]; + } + } else if (pstr_api_struct->config[0].i_channels == 1) { + for (idx = 0; idx < num_samples_read; idx++) { + ptr_input_buffer[write_off_set + (IXHEAACE_MAX_CH_IN_BS_ELE * idx)] = + (FLOAT32)ps_inp_buf[idx]; + } + } + + if (num_ch == 2) { + if (1 == pstr_config->use_drc_element) { + if (16 == pstr_config->ui_pcm_wd_sz) { + for (idx = 0; idx < drc_sample; idx++) { + ptr_drc_inp_buf[idx % num_ch][idx / num_ch + ptr_inp_buf_offset] = + ptr_input_buffer[idx]; + } + } else if (24 == pstr_config->ui_pcm_wd_sz) { + for (idx = 0; idx < drc_sample; idx++) { + i4_inp_data = ((WORD32)(*pi1_inp_buf)) & 0xFF; + pi1_inp_buf++; + i4_inp_data += ((WORD32)(*pi1_inp_buf) << 8) & 0xFFFF; + pi1_inp_buf++; + i4_inp_data += ((WORD32)(*pi1_inp_buf) << 16) & 0xFFFFFF; + pi1_inp_buf++; + i4_inp_data = i4_inp_data - (i4_inp_data >> 23 << 24); + ptr_drc_inp_buf[idx % num_ch][idx / num_ch + ptr_inp_buf_offset] = + (FLOAT32)i4_inp_data / DIV_FAC_24_BIT_PCM; + } + } else if (32 == pstr_config->ui_pcm_wd_sz) { + pi4_inp_buf = (WORD32 *)pi1_inp_buf; + for (idx = 0; idx < drc_sample; idx++) { + i4_inp_data = *pi4_inp_buf++; + ptr_drc_inp_buf[idx % num_ch][idx / num_ch + ptr_inp_buf_offset] = + (FLOAT32)i4_inp_data / DIV_FAC_32_BIT_PCM; + } + } + } + + // update Header and bit-stream parameters + if (0 == pstr_config->sbr_pvc_active) { + sbr_pvc_mode = 0; + } + + ixheaace_set_usac_sbr_params( + pstr_sbr_encoder, usac_independency_flg, 0, pstr_config->sbr_pvc_active, sbr_pvc_mode, + pstr_config->sbr_inter_tes_active, pstr_config->sbr_harmonic, sbr_patching_mode); + + // Downsample SBR input buffer for Harmonic SBR + if (pstr_config->sbr_harmonic) { + FLOAT32 *in_buffer_temp; + ixheaace_get_input_scratch_buf(pstr_api_struct->pstr_state->ptr_temp_buff_resamp, + &in_buffer_temp); + FLOAT32 *outbuf = ixheaace_get_hbe_resample_buffer(pstr_sbr_encoder); + if (pstr_api_struct->config[0].ccfl_idx == SBR_8_3) { + WORD32 input_tot = num_samples_read / pstr_api_struct->config[0].i_channels; + ixheaace_upsampling_inp_buf_generation(ptr_input_buffer, in_buffer_temp, input_tot, + UPSAMPLE_FAC, 0); + } + + // Resampler + for (ch = 0; ch < num_ch; ch++) { + FLOAT32 *shared_buf1_ring, *shared_buf2_ring; + ixheaace_resampler_scratch *pstr_scratch_resampler = + (ixheaace_resampler_scratch *)(ixheaace_resampler_scratch *) + pstr_api_struct->pstr_state->ptr_temp_buff_resamp; + + ia_enhaacplus_enc_get_scratch_bufs(pstr_api_struct->pstr_state->temp_buff_sbr, + &shared_buf1_ring, &shared_buf2_ring); + + if (pstr_api_struct->config[0].ccfl_idx == SBR_8_3) { + // Upsampling by factor 3 - SOS implementation + ia_enhaacplus_enc_iir_sos_upsampler( + &(pstr_api_struct->pstr_state->hbe_up_sampler[0][ch]), in_buffer_temp + ch, + num_samples_read / pstr_api_struct->config[0].i_channels, + IXHEAACE_MAX_CH_IN_BS_ELE, in_buffer_temp + ch, &out_samples, shared_buf1_ring, + shared_buf2_ring, pstr_scratch_resampler); + + // Downsampling by factor 8 + ia_enhaacplus_enc_iir_sos_downsampler( + &(pstr_api_struct->pstr_state->hbe_down_samp_sos[0][ch]), in_buffer_temp + ch, + out_samples, IXHEAACE_MAX_CH_IN_BS_ELE, outbuf + ch, &out_samples, + shared_buf1_ring, shared_buf2_ring, pstr_scratch_resampler); + } else { + WORD32 out_stride = IXHEAACE_MAX_CH_IN_BS_ELE * resamp_ratio; + + ia_enhaacplus_enc_iir_downsampler( + &(pstr_api_struct->pstr_state->hbe_down_sampler[0][ch]), ptr_input_buffer + ch, + num_samples_read / pstr_api_struct->config[0].i_channels, + IXHEAACE_MAX_CH_IN_BS_ELE, outbuf + ch, &out_samples, out_stride, + shared_buf1_ring, shared_buf2_ring, pstr_scratch_resampler); + } + } + } + + // SBR Encode + error = ixheaace_env_encode_frame( + pstr_sbr_encoder, ptr_input_buffer, ptr_input_buffer, + pstr_api_struct->config[0].i_channels, + &(pstr_api_struct->pstr_state->num_anc_data_bytes[0][0]), + pstr_api_struct->pstr_state->anc_data_bytes[0], + &(pstr_api_struct->spectral_band_replication_tabs), &(pstr_api_struct->common_tabs), + &(mps_extension_payload.p_data[0]), mps_extension_payload.data_size, 0, + &pstr_api_struct->pstr_state->str_usac_enc_data.num_sbr_bits); + if (error != IA_NO_ERROR) { + return error; + } + } else { + if (0 == pstr_config->sbr_pvc_active) { + sbr_pvc_mode = 0; + } + + ixheaace_set_usac_sbr_params( + pstr_sbr_encoder, usac_independency_flg, 0, pstr_config->sbr_pvc_active, sbr_pvc_mode, + pstr_config->sbr_inter_tes_active, pstr_config->sbr_harmonic, sbr_patching_mode); + if (pstr_config->sbr_harmonic) { + FLOAT32 *in_buffer_temp; + ixheaace_get_input_scratch_buf(pstr_api_struct->pstr_state->ptr_temp_buff_resamp, + &in_buffer_temp); + FLOAT32 *outbuf = ixheaace_get_hbe_resample_buffer(pstr_sbr_encoder); + if (pstr_api_struct->config[0].ccfl_idx == SBR_8_3) { + WORD32 input_tot = num_samples_read / pstr_api_struct->config[0].i_channels; + ixheaace_upsampling_inp_buf_generation(ptr_input_buffer, in_buffer_temp, input_tot, + UPSAMPLE_FAC, 0); + } + + // Resampler + for (ch = 0; ch < num_ch; ch++) { + FLOAT32 *shared_buf1_ring, *shared_buf2_ring; + ixheaace_resampler_scratch *pstr_scratch_resampler = + (ixheaace_resampler_scratch *)(ixheaace_resampler_scratch *) + pstr_api_struct->pstr_state->ptr_temp_buff_resamp; + + ia_enhaacplus_enc_get_scratch_bufs(pstr_api_struct->pstr_state->temp_buff_sbr, + &shared_buf1_ring, &shared_buf2_ring); + + if (pstr_api_struct->config[0].ccfl_idx == SBR_8_3) { + // Upsampling by factor 3 - SOS implementation + ia_enhaacplus_enc_iir_sos_upsampler( + &(pstr_api_struct->pstr_state->hbe_up_sampler[0][ch]), in_buffer_temp + ch, + num_samples_read / pstr_api_struct->config[0].i_channels, + IXHEAACE_MAX_CH_IN_BS_ELE, in_buffer_temp + ch, &out_samples, shared_buf1_ring, + shared_buf2_ring, pstr_scratch_resampler); + + // Downsampling by factor 8 + ia_enhaacplus_enc_iir_sos_downsampler( + &(pstr_api_struct->pstr_state->hbe_down_samp_sos[0][ch]), in_buffer_temp + ch, + out_samples, IXHEAACE_MAX_CH_IN_BS_ELE, outbuf + ch, &out_samples, + shared_buf1_ring, shared_buf2_ring, pstr_scratch_resampler); + } else { + WORD32 out_stride = IXHEAACE_MAX_CH_IN_BS_ELE * resamp_ratio; + + ia_enhaacplus_enc_iir_downsampler( + &(pstr_api_struct->pstr_state->hbe_down_sampler[0][ch]), + ptr_input_buffer /*input_buffer_fix + write_off_set*/ + ch, + num_samples_read / pstr_api_struct->config[0].i_channels, + IXHEAACE_MAX_CH_IN_BS_ELE, outbuf + ch, &out_samples, out_stride, + shared_buf1_ring, shared_buf2_ring, pstr_scratch_resampler); + } + } + } + + FLOAT32 *time_signal = pstr_api_struct->pstr_state->time_signal; + for (idx = 0; idx < num_samples_read; idx++) { + time_signal[idx] = (FLOAT32)ptr_input_buffer[2 * idx]; + } + + if (1 == pstr_config->use_drc_element) { + if (16 == pstr_config->ui_pcm_wd_sz) { + for (idx = 0; idx < drc_sample; idx++) { + ptr_drc_inp_buf[idx % num_ch][idx / num_ch + ptr_inp_buf_offset] = time_signal[idx]; + } + } else if (24 == pstr_config->ui_pcm_wd_sz) { + for (idx = 0; idx < drc_sample; idx++) { + i4_inp_data = ((WORD32)(*pi1_inp_buf)) & 0xFF; + pi1_inp_buf++; + i4_inp_data += ((WORD32)(*pi1_inp_buf) << 8) & 0xFFFF; + pi1_inp_buf++; + i4_inp_data += ((WORD32)(*pi1_inp_buf) << 16) & 0xFFFFFF; + pi1_inp_buf++; + i4_inp_data = i4_inp_data - (i4_inp_data >> 23 << 24); + ptr_drc_inp_buf[idx % num_ch][idx / num_ch + ptr_inp_buf_offset] = + (FLOAT32)i4_inp_data / DIV_FAC_24_BIT_PCM; + } + } else if (32 == pstr_config->ui_pcm_wd_sz) { + pi4_inp_buf = (WORD32 *)pi1_inp_buf; + for (idx = 0; idx < drc_sample; idx++) { + i4_inp_data = *pi4_inp_buf++; + ptr_drc_inp_buf[idx % num_ch][idx / num_ch + ptr_inp_buf_offset] = + (FLOAT32)i4_inp_data / DIV_FAC_32_BIT_PCM; + } + } + } + + // SBR Encode + error = ixheaace_env_encode_frame( + pstr_sbr_encoder, time_signal, time_signal, pstr_api_struct->config[0].i_channels, + &(pstr_api_struct->pstr_state->num_anc_data_bytes[0][0]), + pstr_api_struct->pstr_state->anc_data_bytes[0], + &(pstr_api_struct->spectral_band_replication_tabs), &(pstr_api_struct->common_tabs), + &(mps_extension_payload.p_data[0]), mps_extension_payload.data_size, 0, NULL); + if (error != IA_NO_ERROR) { + return error; + } + } + + /* Resampling for USAC core */ + { + FLOAT32 *in_buffer_temp; + ixheaace_get_input_scratch_buf(pstr_api_struct->pstr_state->ptr_temp_buff_resamp, + &in_buffer_temp); + if (pstr_api_struct->config[0].ccfl_idx == SBR_8_3) { + WORD32 input_tot = num_samples_read / pstr_api_struct->config[0].i_channels; + ixheaace_upsampling_inp_buf_generation(ptr_input_buffer, in_buffer_temp, input_tot, + UPSAMPLE_FAC, write_off_set); + } + + for (ch = 0; ch < num_ch; ch++) { + FLOAT32 *shared_buf1_ring, *shared_buf2_ring; + ixheaace_resampler_scratch *pstr_scratch_resampler = + (ixheaace_resampler_scratch *)pstr_api_struct->pstr_state->ptr_temp_buff_resamp; + + ia_enhaacplus_enc_get_scratch_bufs(pstr_api_struct->pstr_state->temp_buff_sbr, + &shared_buf1_ring, &shared_buf2_ring); + + if (pstr_api_struct->config[0].ccfl_idx == SBR_8_3) { + // Upsampling by factor 3 - SOS implementation + ia_enhaacplus_enc_iir_sos_upsampler( + &(pstr_api_struct->pstr_state->up_sampler[0][ch]), in_buffer_temp + ch, + num_samples_read / pstr_api_struct->config[0].i_channels, IXHEAACE_MAX_CH_IN_BS_ELE, + in_buffer_temp + ch, &out_samples, shared_buf1_ring, shared_buf2_ring, + pstr_scratch_resampler); + + // Downsampling by factor 8 + ia_enhaacplus_enc_iir_sos_downsampler( + &(pstr_api_struct->pstr_state->down_samp_sos[0][ch]), in_buffer_temp + ch, + out_samples, IXHEAACE_MAX_CH_IN_BS_ELE, ptr_input_buffer + ch, &out_samples, + shared_buf1_ring, shared_buf2_ring, pstr_scratch_resampler); + } else { + WORD32 out_stride = IXHEAACE_MAX_CH_IN_BS_ELE * resamp_ratio; + + ia_enhaacplus_enc_iir_downsampler( + &(pstr_api_struct->pstr_state->down_sampler[0][ch]), + ptr_input_buffer + write_off_set + ch, + num_samples_read / pstr_api_struct->config[0].i_channels, IXHEAACE_MAX_CH_IN_BS_ELE, + ptr_input_buffer + ch, &out_samples, out_stride, shared_buf1_ring, shared_buf2_ring, + pstr_scratch_resampler); + } + } + } + + if (num_ch != 0) { + for (idx = 0; idx < num_ch; idx++) { + ptr_inp_buf[idx] = pstr_api_struct->pstr_state->ptr_in_buf[idx]; + } + + if (16 == pstr_config->ui_pcm_wd_sz) { + if (num_ch == 1) { + for (idx = 0; idx < core_sample; idx++) { + ptr_inp_buf[idx % num_ch][idx / num_ch] = ptr_input_buffer[2 * idx]; + } + } else { + for (idx = 0; idx < core_sample; idx++) { + ptr_inp_buf[idx % num_ch][idx / num_ch] = ptr_input_buffer[idx]; + } + } + } else if (24 == pstr_config->ui_pcm_wd_sz) { + for (idx = 0; idx < core_sample; idx++) { + i4_inp_data = ((WORD32)(*pi1_inp_buf)) & 0xFF; + pi1_inp_buf++; + i4_inp_data += ((WORD32)(*pi1_inp_buf) << 8) & 0xFFFF; + pi1_inp_buf++; + i4_inp_data += ((WORD32)(*pi1_inp_buf) << 16) & 0xFFFFFF; + pi1_inp_buf++; + i4_inp_data = i4_inp_data - (i4_inp_data >> 23 << 24); + ptr_inp_buf[idx % num_ch][idx / num_ch] = (FLOAT32)i4_inp_data / DIV_FAC_24_BIT_PCM; + } + } else if (32 == pstr_config->ui_pcm_wd_sz) { + pi4_inp_buf = (WORD32 *)pi1_inp_buf; + for (idx = 0; idx < core_sample; idx++) { + i4_inp_data = *pi4_inp_buf++; + ptr_inp_buf[idx % num_ch][idx / num_ch] = (FLOAT32)i4_inp_data / DIV_FAC_32_BIT_PCM; + } + } + } + } else { + if (num_ch != 0) { + for (idx = 0; idx < num_ch; idx++) { + ptr_inp_buf[idx] = pstr_api_struct->pstr_state->ptr_in_buf[idx]; + } + + if (16 == pstr_config->ui_pcm_wd_sz) { + for (idx = 0; idx < core_sample; idx++) { + ptr_inp_buf[idx % num_ch][idx / num_ch] = ps_inp_buf[idx]; + } + } else if (24 == pstr_config->ui_pcm_wd_sz) { + for (idx = 0; idx < core_sample; idx++) { + i4_inp_data = ((WORD32)(*pi1_inp_buf)) & 0xFF; + pi1_inp_buf++; + i4_inp_data += ((WORD32)(*pi1_inp_buf) << 8) & 0xFFFF; + pi1_inp_buf++; + i4_inp_data += ((WORD32)(*pi1_inp_buf) << 16) & 0xFFFFFF; + pi1_inp_buf++; + i4_inp_data = i4_inp_data - (i4_inp_data >> 23 << 24); + ptr_inp_buf[idx % num_ch][idx / num_ch] = (FLOAT32)i4_inp_data / DIV_FAC_24_BIT_PCM; + } + } else if (32 == pstr_config->ui_pcm_wd_sz) { + pi4_inp_buf = (WORD32 *)pi1_inp_buf; + for (idx = 0; idx < core_sample; idx++) { + i4_inp_data = *pi4_inp_buf++; + ptr_inp_buf[idx % num_ch][idx / num_ch] = (FLOAT32)i4_inp_data / DIV_FAC_32_BIT_PCM; + } + } + if (1 == pstr_config->use_drc_element) { + if (16 == pstr_config->ui_pcm_wd_sz) { + for (idx = 0; idx < drc_sample; idx++) { + ptr_drc_inp_buf[idx % num_ch][idx / num_ch + ptr_inp_buf_offset] = ps_inp_buf[idx]; + } + } else if (24 == pstr_config->ui_pcm_wd_sz) { + for (idx = 0; idx < drc_sample; idx++) { + i4_inp_data = ((WORD32)(*pi1_inp_buf)) & 0xFF; + pi1_inp_buf++; + i4_inp_data += ((WORD32)(*pi1_inp_buf) << 8) & 0xFFFF; + pi1_inp_buf++; + i4_inp_data += ((WORD32)(*pi1_inp_buf) << 16) & 0xFFFFFF; + pi1_inp_buf++; + i4_inp_data = i4_inp_data - (i4_inp_data >> 23 << 24); + ptr_drc_inp_buf[idx % num_ch][idx / num_ch + ptr_inp_buf_offset] = + (FLOAT32)i4_inp_data / DIV_FAC_24_BIT_PCM; + } + } else if (32 == pstr_config->ui_pcm_wd_sz) { + pi4_inp_buf = (WORD32 *)pi1_inp_buf; + for (idx = 0; idx < drc_sample; idx++) { + i4_inp_data = *pi4_inp_buf++; + ptr_drc_inp_buf[idx % num_ch][idx / num_ch + ptr_inp_buf_offset] = + (FLOAT32)i4_inp_data / DIV_FAC_32_BIT_PCM; + } + } + } + } + } + + if (pstr_sig_class_data->is_switch_mode) { + for (idx = 0; idx < core_coder_frame_length; idx++) { + pstr_sig_class_data->input_samples[pstr_sig_class_data->n_buffer_samples + idx] = + pstr_api_struct->pstr_state->ptr_in_buf[0][idx]; + } + pstr_sig_class_data->n_buffer_samples += core_coder_frame_length; + iusace_classification(pstr_sig_class_data, pstr_scratch, core_coder_frame_length); + } + + pstr_it_bit_buff = + iusace_create_bit_buffer(pstr_it_bit_buff, pstr_api_struct->pp_mem[IA_MEMTYPE_OUTPUT], + pstr_api_struct->pstr_mem_info[IA_MEMTYPE_OUTPUT].ui_size, 1); + if (pstr_it_bit_buff == NULL) { + return -1; + } +#ifdef ENABLE_SET_JUMP + pstr_it_bit_buff->iusace_jmp_buf = &api_execute_jmp_buf; +#endif + error = + ixheaace_usac_encode(pstr_api_struct->pstr_state->ptr_in_buf, pstr_config, + &pstr_api_struct->pstr_state->str_usac_enc_data, + &pstr_api_struct->pstr_state->audio_specific_config, pstr_it_bit_buff, + pstr_sbr_encoder, pstr_api_struct->pstr_state->pp_drc_in_buf); + if (error) return error; + + padding_bits = 8 - (pstr_it_bit_buff->cnt_bits & 7); + if (padding_bits > 0 && padding_bits < 8) { + ps_out_buf[pstr_it_bit_buff->cnt_bits >> 3] = + (WORD8)((UWORD32)ps_out_buf[pstr_it_bit_buff->cnt_bits >> 3]) & (0xFF << padding_bits); + } + pstr_api_struct->pstr_state->i_out_bytes = + (padding_bits > 0 && padding_bits < 8) ? (pstr_it_bit_buff->cnt_bits + padding_bits) >> 3 + : pstr_it_bit_buff->cnt_bits >> 3; + + pstr_state->str_usac_enc_data.frame_count++; + pstr_usac_data->usac_independency_flag_count = + (pstr_usac_data->usac_independency_flag_count + 1) % + pstr_usac_data->usac_independency_flag_interval; + + if (pstr_config->sbr_enable) { + WORD32 num_samples = pstr_api_struct->config[0].usac_config.ccfl * IXHEAACE_MAX_CH_IN_BS_ELE; + switch (pstr_api_struct->config[0].ccfl_idx) { + case SBR_8_3: + num_samples *= 8; + num_samples /= 3; + break; + + case SBR_2_1: + num_samples *= 2; + break; + + case SBR_4_1: + num_samples *= 4; + break; + } + + if (ptr_input_buffer != NULL) { + memmove(ptr_input_buffer, ptr_input_buffer + num_samples, + write_off_set * sizeof(ptr_input_buffer[0])); + } + } + return IA_NO_ERROR; +} IA_ERRORCODE ixheaace_get_lib_id_strings(pVOID pv_output) { IA_ERRORCODE err_code = IA_NO_ERROR; ixheaace_version *pstr_output_config = (ixheaace_version *)pv_output; @@ -1915,7 +3295,7 @@ IA_ERRORCODE ixheaace_allocate(pVOID pv_input, pVOID pv_output) { if (pstr_input_config->aot != AOT_AAC_ELD && pstr_input_config->aot != AOT_AAC_LC && pstr_input_config->aot != AOT_AAC_LD && pstr_input_config->aot != AOT_SBR && - pstr_input_config->aot != AOT_PS) { + pstr_input_config->aot != AOT_PS && pstr_input_config->aot != AOT_USAC) { return IA_EXHEAACE_API_FATAL_UNSUPPORTED_AOT; } ui_api_size = sizeof(ixheaace_api_struct); @@ -2072,7 +3452,10 @@ IA_ERRORCODE ixheaace_init(pVOID pstr_obj_ixheaace, pVOID pv_input, pVOID pv_out ixheaace_get_audiospecific_config_bytes(pstr_ia_asc_bit_buf, &pstr_api_struct->pstr_state->audio_specific_config, - pstr_api_struct->pstr_state->aot); + pstr_api_struct->pstr_state->aot + + , + pstr_input_config->ccfl_idx); pstr_api_struct->pstr_state->i_out_bytes = (pstr_ia_asc_bit_buf->cnt_bits + 7) >> 3; } @@ -2117,6 +3500,39 @@ IA_ERRORCODE ixheaace_init(pVOID pstr_obj_ixheaace, pVOID pv_input, pVOID pv_out } } + else { + pstr_api_struct->pstr_state->pstr_config[0] = &pstr_api_struct->config[0]; + error = ia_usac_enc_init(pstr_api_struct, pstr_input_config->ccfl_idx); + if (error) { + return error; + } + pstr_output_config->input_size = + frame_length * channels * (pstr_api_struct->config[0].usac_config.ui_pcm_wd_sz >> 3); + pstr_output_config->down_sampling_ratio = 1; + if (pstr_api_struct->config[0].usac_config.sbr_enable == 1) { + switch (pstr_api_struct->config[0].ccfl_idx) { + case SBR_8_3: + pstr_output_config->input_size *= 8; + pstr_output_config->input_size /= 3; + pstr_output_config->down_sampling_ratio = 8.0f / 3.0f; + break; + + case SBR_2_1: + pstr_output_config->input_size *= 2; + pstr_output_config->down_sampling_ratio = 2; + break; + + case SBR_4_1: + pstr_output_config->input_size *= 4; + pstr_output_config->down_sampling_ratio = 4; + break; + } + } + pstr_output_config->samp_freq = pstr_api_struct->config[0].usac_config.native_sample_rate; + pstr_output_config->header_samp_freq = + pstr_api_struct->config[0].usac_config.native_sample_rate; + pstr_output_config->audio_profile = AUDIO_PROFILE_USAC_L2; + } pstr_api_struct->pstr_state->ui_init_done = 1; pstr_output_config->i_out_bytes = pstr_api_struct->pstr_state->i_out_bytes; @@ -2141,10 +3557,13 @@ IA_ERRORCODE ixheaace_process(pVOID pstr_obj_ixheaace, pVOID pv_input, pVOID pv_ ixheaace_api_struct *pstr_api_struct = (ixheaace_api_struct *)pstr_obj_ixheaace; ixheaace_output_config *pstr_output_config = (ixheaace_output_config *)pv_output; - for (ele_idx = 0; ele_idx < pstr_api_struct->config[0].num_bs_elements; ele_idx++) { - error = ia_enhaacplus_enc_execute(pstr_api_struct, ele_idx); + if (!pstr_api_struct->usac_en) { + for (ele_idx = 0; ele_idx < pstr_api_struct->config[0].num_bs_elements; ele_idx++) { + error = ia_enhaacplus_enc_execute(pstr_api_struct, ele_idx); + } + } else { + error = iusace_process(pstr_api_struct); } - pstr_output_config->i_out_bytes = pstr_api_struct->pstr_state->i_out_bytes; return error; diff --git a/encoder/ixheaace_api.h b/encoder/ixheaace_api.h index cf15184..6631092 100644 --- a/encoder/ixheaace_api.h +++ b/encoder/ixheaace_api.h @@ -79,6 +79,7 @@ typedef struct { WORD32 frame_cmd_flag; WORD32 out_bytes_flag; WORD32 user_tns_flag; + WORD32 user_esbr_flag; WORD32 aot; WORD32 i_mps_tree_config; WORD32 esbr_flag; @@ -91,6 +92,17 @@ typedef struct { WORD32 i_use_mps; WORD32 i_use_adts; WORD32 i_use_es; + WORD32 usac_en; + WORD32 codec_mode; + WORD32 cplx_pred; + WORD32 ccfl_idx; + WORD32 pvc_active; + WORD32 harmonic_sbr; + WORD32 inter_tes_active; + ia_drc_input_config str_drc_cfg; + FLAG use_drc_element; + WORD32 drc_frame_size; + WORD32 hq_esbr; FLAG write_program_config_element; ixheaace_aac_enc_config aac_config; } ixheaace_input_config; diff --git a/encoder/ixheaace_api_defs.h b/encoder/ixheaace_api_defs.h index 5ad4986..3160077 100644 --- a/encoder/ixheaace_api_defs.h +++ b/encoder/ixheaace_api_defs.h @@ -37,3 +37,10 @@ #define IA_LAST_COMP_APIVERSION \ IA_MAKE_VERSION_STR(IA_LASTCOMP_APIVERSION_MAJOR, IA_LASTCOMP_APIVERSION_MINOR) + +IA_ERRORCODE ixheaace_usac_encode(FLOAT32 **ptr_input, + ia_usac_encoder_config_struct *ptr_usac_config, + ia_usac_data_struct *pstr_state, + ixheaace_audio_specific_config_struct *pstr_asc, + ia_bit_buf_struct *pstr_it_bit_buff, + ixheaace_pstr_sbr_enc ptr_env_encoder, FLOAT32 **ptr_drc_inp); diff --git a/encoder/ixheaace_asc_write.c b/encoder/ixheaace_asc_write.c index b96c887..bc28857 100644 --- a/encoder/ixheaace_asc_write.c +++ b/encoder/ixheaace_asc_write.c @@ -20,14 +20,26 @@ #include #include "iusace_type_def.h" -#include "ixheaace_api.h" #include "iusace_bitbuffer.h" - +/* DRC */ +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" +#include "impd_drc_uni_drc_eq.h" +#include "impd_drc_uni_drc_filter_bank.h" +#include "impd_drc_gain_enc.h" +#include "impd_drc_struct_def.h" #include "iusace_cnst.h" + +#include "ixheaace_api.h" +#include "iusace_tns_usac.h" +#include "iusace_psy_mod.h" #include "ixheaace_sbr_header.h" #include "ixheaace_config.h" #include "iusace_config.h" #include "ixheaace_asc_write.h" +#include "iusace_block_switch_const.h" #include "iusace_rom.h" #include "ixheaac_constants.h" #include "ixheaace_aac_constants.h" @@ -48,7 +60,208 @@ static WORD32 ixheaace_spatial_specific_config(ia_bit_buf_struct *pstr_it_bit_bu return bit_cnt; } +static WORD32 iusace_config_extension(ia_bit_buf_struct *pstr_it_bit_buff, + ia_usac_config_struct *pstr_usac_config) { + WORD32 bit_cnt = 0; + UWORD32 i, j; + UWORD32 fill_byte_val = 0xa5; + bit_cnt += iusace_write_escape_value(pstr_it_bit_buff, + pstr_usac_config->num_config_extensions - 1, 2, 4, 8); + + for (j = 0; j < pstr_usac_config->num_config_extensions; j++) { + bit_cnt += iusace_write_escape_value(pstr_it_bit_buff, + pstr_usac_config->usac_config_ext_type[j], 4, 8, 16); + + bit_cnt += iusace_write_escape_value(pstr_it_bit_buff, + pstr_usac_config->usac_config_ext_len[j], 4, 8, 16); + + switch (pstr_usac_config->usac_config_ext_type[j]) { + case ID_CONFIG_EXT_FILL: + for (i = 0; i < pstr_usac_config->usac_config_ext_len[j]; i++) { + bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, fill_byte_val, 8); + } + break; + case ID_CONFIG_EXT_LOUDNESS_INFO: + for (i = 0; i < pstr_usac_config->usac_config_ext_len[j]; i++) { + bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, + pstr_usac_config->usac_config_ext_buf[j][i], 8); + } + break; + default: + for (i = 0; i < pstr_usac_config->usac_config_ext_len[j]; i++) { + bit_cnt += iusace_write_bits_buf( + pstr_it_bit_buff, (UWORD32)pstr_usac_config->usac_cfg_ext_info_buf[j][i], 8); + } + break; + } + } + return bit_cnt; +} + +static WORD32 iusace_sbr_config(ia_bit_buf_struct *pstr_it_bit_buff, + ia_usac_enc_sbr_config_struct *pstr_usac_sbr_config) { + WORD32 bit_cnt = 0; + + bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (pstr_usac_sbr_config->harmonic_sbr), 1); + bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (pstr_usac_sbr_config->bs_inter_tes), 1); + bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (pstr_usac_sbr_config->bs_pvc), 1); + bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (pstr_usac_sbr_config->dflt_start_freq), 4); + bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (pstr_usac_sbr_config->dflt_stop_freq), 4); + bit_cnt += + iusace_write_bits_buf(pstr_it_bit_buff, (pstr_usac_sbr_config->dflt_header_extra1), 1); + bit_cnt += + iusace_write_bits_buf(pstr_it_bit_buff, (pstr_usac_sbr_config->dflt_header_extra2), 1); + + if (pstr_usac_sbr_config->dflt_header_extra1) { + bit_cnt += + iusace_write_bits_buf(pstr_it_bit_buff, (pstr_usac_sbr_config->dflt_freq_scale), 2); + bit_cnt += + iusace_write_bits_buf(pstr_it_bit_buff, (pstr_usac_sbr_config->dflt_alter_scale), 2); + bit_cnt += + iusace_write_bits_buf(pstr_it_bit_buff, (pstr_usac_sbr_config->dflt_noise_bands), 2); + } + + if (pstr_usac_sbr_config->dflt_header_extra2) { + bit_cnt += + iusace_write_bits_buf(pstr_it_bit_buff, (pstr_usac_sbr_config->dflt_limiter_bands), 2); + bit_cnt += + iusace_write_bits_buf(pstr_it_bit_buff, (pstr_usac_sbr_config->dflt_limiter_gains), 2); + bit_cnt += + iusace_write_bits_buf(pstr_it_bit_buff, (pstr_usac_sbr_config->dflt_interpol_freq), 1); + bit_cnt += + iusace_write_bits_buf(pstr_it_bit_buff, (pstr_usac_sbr_config->dflt_smoothing_mode), 1); + } + + return bit_cnt; +} + +static WORD32 iusace_cpe_config(ia_bit_buf_struct *pstr_it_bit_buff, + ia_usac_enc_element_config_struct *pstr_usac_enc_conf, + WORD32 sbr_ratio_idx, ia_aace_config_struct *pstr_eld_config) { + WORD32 bit_count = 0; + + if (sbr_ratio_idx > 0) { + bit_count += iusace_sbr_config(pstr_it_bit_buff, &(pstr_usac_enc_conf->str_usac_sbr_config)); + bit_count += + iusace_write_bits_buf(pstr_it_bit_buff, (pstr_usac_enc_conf->stereo_config_index), 2); + } + + if (pstr_usac_enc_conf->stereo_config_index > 0) { + if (pstr_eld_config->num_sac_cfg_bits) { + { + bit_count += ixheaace_spatial_specific_config(pstr_it_bit_buff, pstr_eld_config); + } + } + } + + return bit_count; +} +static WORD32 iusace_ext_element_config(ia_bit_buf_struct *pstr_it_bit_buff, + ia_usac_enc_element_config_struct *pstr_usac_enc_conf) { + WORD32 bit_count = 0; + + bit_count += iusace_write_escape_value(pstr_it_bit_buff, pstr_usac_enc_conf->usac_ext_ele_type, + 4, 8, 16); + bit_count += iusace_write_escape_value(pstr_it_bit_buff, + pstr_usac_enc_conf->usac_ext_ele_cfg_len, 4, 8, 16); + bit_count += iusace_write_bits_buf(pstr_it_bit_buff, + (pstr_usac_enc_conf->usac_ext_ele_dflt_len_present), 1); + + if (pstr_usac_enc_conf->usac_ext_ele_dflt_len_present) { + bit_count += iusace_write_escape_value( + pstr_it_bit_buff, pstr_usac_enc_conf->usac_ext_ele_dflt_len - 1, 8, 16, 0); + } + bit_count += iusace_write_bits_buf(pstr_it_bit_buff, + (pstr_usac_enc_conf->usac_ext_ele_payload_present), 1); + + switch (pstr_usac_enc_conf->usac_ext_ele_type) { + case ID_EXT_ELE_FILL: + break; + case ID_EXT_ELE_UNI_DRC: { + UWORD32 i; + for (i = 0; i < pstr_usac_enc_conf->usac_ext_ele_cfg_len; i++) { + bit_count += + iusace_write_bits_buf(pstr_it_bit_buff, pstr_usac_enc_conf->drc_config_data[i], 8); + } + } break; + default: + break; + } + + return bit_count; +} + +static WORD32 iusace_encoder_config(ia_bit_buf_struct *pstr_it_bit_buff, + ia_usac_config_struct *pstr_usac_cfg, WORD32 sbr_ratio_idx, + ia_aace_config_struct *pstr_eld_config) { + WORD32 bit_cnt = 0; + UWORD32 elem_idx = 0; + ia_usac_enc_element_config_struct *pstr_usac_enc_conf; + + bit_cnt += + iusace_write_escape_value(pstr_it_bit_buff, pstr_usac_cfg->num_elements - 1, 4, 8, 16); + + for (elem_idx = 0; elem_idx < pstr_usac_cfg->num_elements; elem_idx++) { + unsigned long tmp = pstr_usac_cfg->usac_element_type[elem_idx]; + pstr_usac_enc_conf = &pstr_usac_cfg->str_usac_element_config[elem_idx]; + bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, tmp, 2); + + switch (pstr_usac_cfg->usac_element_type[elem_idx]) { + case ID_USAC_SCE: + bit_cnt += iusace_write_bits_buf( + pstr_it_bit_buff, (pstr_usac_enc_conf->tw_mdct), + 1); // For extended HE AAC profile tw_mdct shall be encoded with 0. + bit_cnt += + iusace_write_bits_buf(pstr_it_bit_buff, (pstr_usac_enc_conf->noise_filling), 1); + if (sbr_ratio_idx > 0) { + bit_cnt += + iusace_sbr_config(pstr_it_bit_buff, &(pstr_usac_enc_conf->str_usac_sbr_config)); + } + break; + case ID_USAC_CPE: + bit_cnt += iusace_write_bits_buf( + pstr_it_bit_buff, (pstr_usac_enc_conf->tw_mdct), + 1); // For extended HE AAC profile tw_mdct shall be encoded with 0. + bit_cnt += + iusace_write_bits_buf(pstr_it_bit_buff, (pstr_usac_enc_conf->noise_filling), 1); + bit_cnt += iusace_cpe_config(pstr_it_bit_buff, pstr_usac_enc_conf, sbr_ratio_idx, + pstr_eld_config); + break; + case ID_USAC_EXT: + bit_cnt += iusace_ext_element_config(pstr_it_bit_buff, pstr_usac_enc_conf); + break; + default: + return -1; + ; + break; + } + } + + return bit_cnt; +} + +static UWORD32 ixheaace_sbr_ratio(UWORD32 core_sbr_framelength_idx) { + UWORD32 sbr_ratio_index = 0x0FF; + + switch (core_sbr_framelength_idx) { + case 0: + case 1: + sbr_ratio_index = USAC_SBR_RATIO_NO_SBR; + break; + case 2: + sbr_ratio_index = USAC_SBR_RATIO_INDEX_8_3; + break; + case 3: + sbr_ratio_index = USAC_SBR_RATIO_INDEX_2_1; + break; + case 4: + sbr_ratio_index = USAC_SBR_RATIO_INDEX_4_1; + break; + } + + return sbr_ratio_index; +} static WORD32 sbr_header(ia_bit_buf_struct *pstr_it_bit_buff, ixheaace_pstr_sbr_hdr_data pstr_sbr_config) { WORD32 bit_cnt = 0; @@ -77,9 +290,9 @@ static WORD32 sbr_header(ia_bit_buf_struct *pstr_it_bit_buff, static WORD32 ld_sbr_header(ia_bit_buf_struct *pstr_it_bit_buff, ixheaace_pstr_sbr_hdr_data pstr_sbr_config, - WORD32 channelConfiguration) { + WORD32 channel_configuration) { WORD32 num_sbr_header, el, bit_cnt = 0; - switch (channelConfiguration) { + switch (channel_configuration) { case 1: case 2: num_sbr_header = 1; @@ -107,7 +320,7 @@ static WORD32 ld_sbr_header(ia_bit_buf_struct *pstr_it_bit_buff, static WORD32 iaace_get_eld_specific_config_bytes(ia_bit_buf_struct *pstr_it_bit_buff, ia_aace_config_struct *pstr_eld_config, - WORD32 channelConfiguration) { + WORD32 channel_configuration) { WORD32 bit_cnt = 0; bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (pstr_eld_config->frame_length_flag), 1); bit_cnt += @@ -121,7 +334,8 @@ static WORD32 iaace_get_eld_specific_config_bytes(ia_bit_buf_struct *pstr_it_bit if (pstr_eld_config->ld_sbr_present_flag) { bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (pstr_eld_config->ld_sbr_sample_rate), 1); bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (pstr_eld_config->ld_sbr_crc_flag), 1); - bit_cnt += ld_sbr_header(pstr_it_bit_buff, pstr_eld_config->sbr_config, channelConfiguration); + bit_cnt += + ld_sbr_header(pstr_it_bit_buff, pstr_eld_config->sbr_config, channel_configuration); } if (pstr_eld_config->num_sac_cfg_bits) { @@ -139,7 +353,7 @@ static WORD32 iaace_get_eld_specific_config_bytes(ia_bit_buf_struct *pstr_it_bit static WORD32 iaace_ga_specific_config_bytes(ia_bit_buf_struct *pstr_it_bit_buff, ia_aace_config_struct *pstr_ga_specific_config, - WORD32 channelConfiguration, WORD32 aot) { + WORD32 channel_configuration, WORD32 aot) { WORD32 bit_cnt = 0; bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (pstr_ga_specific_config->frame_length_flag), 1); @@ -149,7 +363,7 @@ static WORD32 iaace_ga_specific_config_bytes(ia_bit_buf_struct *pstr_it_bit_buff bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (pstr_ga_specific_config->core_coder_delay), 14); } - if (!channelConfiguration) { + if (!channel_configuration) { } if (AOT_AAC_LD == aot) { @@ -177,7 +391,8 @@ static WORD32 iaace_ga_specific_config_bytes(ia_bit_buf_struct *pstr_it_bit_buff WORD32 ixheaace_get_audiospecific_config_bytes( ia_bit_buf_struct *pstr_it_bit_buff, - ixheaace_audio_specific_config_struct *pstr_audio_specific_config, WORD32 aot) { + ixheaace_audio_specific_config_struct *pstr_audio_specific_config, WORD32 aot, + WORD32 ccfl_idx) { WORD32 bit_cnt = 0, i; UWORD32 tmp = 0x0f; // initialized to indicate no sampling frequency index field WORD32 ext_aot = -1; @@ -197,8 +412,15 @@ WORD32 ixheaace_get_audiospecific_config_bytes( } } pstr_audio_specific_config->audio_object_type = aot; - - { + if (aot == AOT_USAC) { + for (i = 0; i < sizeof(iusace_sampl_freq_idx_table) / sizeof(iusace_sampl_freq_idx_table[0]); + i++) { + if (pstr_audio_specific_config->sampling_frequency == iusace_sampl_freq_idx_table[i]) { + tmp = i; + break; + } + } + } else { for (i = 0; i < sizeof(ia_sampl_freq_table) / sizeof(ia_sampl_freq_table[0]); i++) { if (ia_sampl_freq_table[i] == pstr_audio_specific_config->sampling_frequency) { tmp = i; @@ -227,9 +449,9 @@ WORD32 ixheaace_get_audiospecific_config_bytes( if (pstr_audio_specific_config->samp_freq_index == 0xf) { bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (pstr_audio_specific_config->sampling_frequency), 24); - } else { + } else if (AOT_USAC != aot) { pstr_audio_specific_config->sampling_frequency = - iusace_sampl_freq_table[pstr_audio_specific_config->samp_freq_index]; + ia_sampl_freq_table[pstr_audio_specific_config->samp_freq_index]; } bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, (pstr_audio_specific_config->channel_configuration), 4); @@ -299,6 +521,90 @@ WORD32 ixheaace_get_audiospecific_config_bytes( } break; } + + case AOT_USAC: { + WORD32 sbr_ratio_idx; + ia_usac_config_struct *pstr_usac_config = &(pstr_audio_specific_config->str_usac_config); + WORD32 ia_ccfl_tbl[5] = {768, 1024, 768, 1024, 1024}; + pstr_audio_specific_config->core_sbr_framelength_index = + ccfl_idx; // 768 core coder frame length without SBR + pstr_usac_config->ccfl = + ia_ccfl_tbl[pstr_audio_specific_config->core_sbr_framelength_index]; + tmp = 0x1f; + for (i = 0; i < sizeof(ia_usac_sampl_freq_table) / sizeof(ia_usac_sampl_freq_table[0]); + i++) { + if (ia_usac_sampl_freq_table[i] == pstr_audio_specific_config->sampling_frequency) { + tmp = i; + break; + } + } + pstr_audio_specific_config->samp_freq_index = (UWORD32)tmp; + + if (pstr_audio_specific_config->samp_freq_index == 0x1f) { + bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, 0x1f, 5); + bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, + (pstr_audio_specific_config->sampling_frequency), 24); + } else { + bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, + (pstr_audio_specific_config->samp_freq_index), 5); + } + + bit_cnt += iusace_write_bits_buf( + pstr_it_bit_buff, (pstr_audio_specific_config->core_sbr_framelength_index), 3); + + bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, + (pstr_audio_specific_config->channel_configuration), 5); + + if (pstr_audio_specific_config->channel_configuration == 0) { + bit_cnt += iusace_write_escape_value( + pstr_it_bit_buff, pstr_audio_specific_config->num_audio_channels, 5, 8, 16); + + for (i = 0; i < pstr_audio_specific_config->num_audio_channels; i++) { + tmp = pstr_audio_specific_config->output_channel_pos[i]; + bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, tmp, 5); + } + } + + sbr_ratio_idx = ixheaace_sbr_ratio(pstr_audio_specific_config->core_sbr_framelength_index); + + bit_cnt += iusace_encoder_config(pstr_it_bit_buff, pstr_usac_config, sbr_ratio_idx, + &pstr_audio_specific_config->str_aac_config); + + bit_cnt += + iusace_write_bits_buf(pstr_it_bit_buff, pstr_usac_config->usac_cfg_ext_present, 1); + if (pstr_usac_config->usac_cfg_ext_present) { + bit_cnt += iusace_config_extension(pstr_it_bit_buff, pstr_usac_config); + } + + if (sbr_ratio_idx) + pstr_audio_specific_config->sbr_present_flag = 1; + else + pstr_audio_specific_config->sbr_present_flag = 0; + + pstr_audio_specific_config->ext_audio_object_type = 0; + + if (pstr_audio_specific_config->ext_audio_object_type == AOT_SBR) { + pstr_audio_specific_config->ext_sync_word = 0x2b7; + bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, + (pstr_audio_specific_config->ext_sync_word), 11); + + bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, + (pstr_audio_specific_config->ext_audio_object_type), 5); + + bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, + (pstr_audio_specific_config->sbr_present_flag), 1); + + if (pstr_audio_specific_config->sbr_present_flag == 1) { + bit_cnt += iusace_write_bits_buf(pstr_it_bit_buff, + (pstr_audio_specific_config->ext_samp_freq_index), 4); + + if (pstr_audio_specific_config->ext_samp_freq_index == 0xf) { + bit_cnt += iusace_write_bits_buf( + pstr_it_bit_buff, (pstr_audio_specific_config->ext_sampling_frequency), 24); + } + } + } + } default: break; } diff --git a/encoder/ixheaace_asc_write.h b/encoder/ixheaace_asc_write.h index 87346bb..27596c5 100644 --- a/encoder/ixheaace_asc_write.h +++ b/encoder/ixheaace_asc_write.h @@ -34,9 +34,11 @@ typedef struct { WORD32 sbr_present_flag; WORD32 cfg_ext_present; WORD32 ext_sync_word; + ia_usac_config_struct str_usac_config; ia_aace_config_struct str_aac_config; } ixheaace_audio_specific_config_struct; WORD32 ixheaace_get_audiospecific_config_bytes( ia_bit_buf_struct *pstr_it_bit_buff, - ixheaace_audio_specific_config_struct *pstr_audio_specific_config, WORD32 aot); \ No newline at end of file + ixheaace_audio_specific_config_struct *pstr_audio_specific_config, WORD32 aot, + WORD32 ccfl_idx); \ No newline at end of file diff --git a/encoder/ixheaace_bits_count.c b/encoder/ixheaace_bits_count.c index fdf5d99..da938ef 100644 --- a/encoder/ixheaace_bits_count.c +++ b/encoder/ixheaace_bits_count.c @@ -21,6 +21,10 @@ #include #include "ixheaac_type_def.h" #include "ixheaac_constants.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" #include "ixheaace_api.h" #include "ixheaace_aac_constants.h" diff --git a/encoder/ixheaace_block_switch.c b/encoder/ixheaace_block_switch.c index 68d71e4..25fa0ae 100644 --- a/encoder/ixheaace_block_switch.c +++ b/encoder/ixheaace_block_switch.c @@ -31,6 +31,7 @@ #include "ixheaac_basic_ops40.h" #include "ixheaac_basic_ops.h" #include "ixheaace_block_switch.h" +#include "iusace_block_switch_struct_def.h" #include static FLOAT32 iaace_fmult(FLOAT32 a, FLOAT32 b) { return (a * b); } diff --git a/encoder/ixheaace_channel_map.c b/encoder/ixheaace_channel_map.c index 0477ea2..2a00651 100644 --- a/encoder/ixheaace_channel_map.c +++ b/encoder/ixheaace_channel_map.c @@ -19,10 +19,14 @@ */ #include +#include #include "ixheaac_type_def.h" #include "ixheaac_constants.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" #include "ixheaace_api.h" -#include #include "ixheaac_error_standards.h" #include "ixheaace_error_codes.h" #include "ixheaace_aac_constants.h" diff --git a/encoder/ixheaace_common_utils.h b/encoder/ixheaace_common_utils.h index d615a03..282ae74 100644 --- a/encoder/ixheaace_common_utils.h +++ b/encoder/ixheaace_common_utils.h @@ -27,6 +27,8 @@ #define ia_mul_flt(a, b) ((a) * (b)) #define ia_negate_flt(a) (-a) +#define MASK 0x0001 + #define C70 (-0.1666667014f) //(cos(u) + cos(2 * u) + cos(3 * u)) / 3; #define C71 (0.7901564837f) //(2 * cos(u) - cos(2 * u) - cos(3 * u)) / 3; #define C72 (0.0558542535f) //(cos(u) - 2 * cos(2 * u) + cos(3 * u)) / 3; diff --git a/encoder/ixheaace_config_params.h b/encoder/ixheaace_config_params.h index 79185c7..f0414d5 100644 --- a/encoder/ixheaace_config_params.h +++ b/encoder/ixheaace_config_params.h @@ -55,4 +55,4 @@ #define USAC_COMPLEX_PREDECTION_DEFAULT_VALUE (0) #define USAC_TNS_DEFAULT_VALUE (0) #define USAC_FLAG_NOISE_FILLING_DEFAULT_VALUE (0) -#define USAC_BITRATE_DEFAULT_VALUE (32000) +#define USAC_BITRATE_DEFAULT_VALUE (96000) diff --git a/encoder/ixheaace_cplx_pred.c b/encoder/ixheaace_cplx_pred.c new file mode 100644 index 0000000..703941e --- /dev/null +++ b/encoder/ixheaace_cplx_pred.c @@ -0,0 +1,522 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include + +#include "iusace_type_def.h" +#include "ixheaac_error_standards.h" +#include "ixheaace_error_codes.h" +#include "ixheaace_mps_common_define.h" +#include "iusace_cnst.h" +#include "iusace_fd_quant.h" +#include "iusace_bitbuffer.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_api.h" +#include "impd_drc_uni_drc_eq.h" +#include "impd_drc_uni_drc_filter_bank.h" +#include "impd_drc_gain_enc.h" +#include "impd_drc_struct_def.h" + +#include "ixheaace_memory_standards.h" +#include "iusace_tns_usac.h" +#include "iusace_psy_mod.h" +#include "iusace_config.h" +#include "iusace_block_switch_const.h" +#include "iusace_block_switch_struct_def.h" +#include "iusace_signal_classifier.h" +#include "iusace_ms.h" +#include "ixheaace_adjust_threshold_data.h" +#include "iusace_fd_qc_util.h" +#include "ixheaace_sbr_header.h" +#include "ixheaace_config.h" +#include "ixheaace_asc_write.h" +#include "iusace_main.h" +#include "iusace_rom.h" + +static VOID iusace_compute_pred_coef(WORD32 num_lines, WORD32 complex_coef, + FLOAT64 *ptr_spec_mdct_dmx, FLOAT64 *ptr_spec_mdst_dmx, + FLOAT64 *ptr_spec_mdct_mid_side, FLOAT32 *pred_coef_re, + FLOAT32 *pred_coef_im, FLOAT32 *pred_coef_q_re, + FLOAT32 *pred_coef_q_im, WORD32 *pred_coef_q_int_re, + WORD32 *pred_coef_q_int_im) { + LOOPIDX bin_idx; + FLOAT32 iprod_re = 0.0f, iprod_im = 0.0f; + FLOAT32 eps = 1.0e-6f; + const FLOAT32 k_delta = 0.1f; + const FLOAT32 k_max = 3.0f; + WORD32 pred_coef_sign_re, pred_coef_sign_im; + FLOAT32 pred_coef_abs_re, pred_coef_abs_im; + FLOAT32 abs_dmx = 0.0f; + + for (bin_idx = 0; bin_idx < num_lines; bin_idx++) { + /* D = Dr + jDi */ + /* D*S = (Dr + jDi)*S = Dr*S + j(Di*S) */ + /* alpha = alpha_r - jalpha_i */ + if (complex_coef == 1) { + iprod_re += (FLOAT32)(ptr_spec_mdct_dmx[bin_idx] * ptr_spec_mdct_mid_side[bin_idx]); + iprod_im += (FLOAT32)(ptr_spec_mdst_dmx[bin_idx] * ptr_spec_mdct_mid_side[bin_idx]); + abs_dmx += (FLOAT32)(ptr_spec_mdct_dmx[bin_idx] * ptr_spec_mdct_dmx[bin_idx] + + ptr_spec_mdst_dmx[bin_idx] * ptr_spec_mdst_dmx[bin_idx]); + } else { + iprod_re += (FLOAT32)(ptr_spec_mdct_dmx[bin_idx] * ptr_spec_mdct_mid_side[bin_idx]); + abs_dmx += (FLOAT32)(ptr_spec_mdct_dmx[bin_idx] * ptr_spec_mdct_dmx[bin_idx]); + } + } + + /* Compute real and imaginary parts of prediction coefficient */ + *pred_coef_re = iprod_re / (abs_dmx + eps); + pred_coef_sign_re = *pred_coef_re > 0 ? 1 : -1; + pred_coef_abs_re = (FLOAT32)MIN(fabs(*pred_coef_re), k_max); + *pred_coef_q_int_re = pred_coef_sign_re * (WORD32)(pred_coef_abs_re / k_delta + 0.5f); + *pred_coef_q_re = *pred_coef_q_int_re * k_delta; + + if (complex_coef == 1) { + *pred_coef_im = iprod_im / (abs_dmx + eps); + pred_coef_sign_im = *pred_coef_im > 0 ? 1 : -1; + pred_coef_abs_im = (FLOAT32)MIN(fabs(*pred_coef_im), k_max); + *pred_coef_q_int_im = pred_coef_sign_im * (WORD32)(pred_coef_abs_im / k_delta + 0.5f); + *pred_coef_q_im = *pred_coef_q_int_im * k_delta; + } +} + +static VOID iusace_compute_res(WORD32 num_lines, WORD32 complex_coef, FLOAT32 pred_coef_q_re, + FLOAT32 pred_coef_q_im, FLOAT64 *ptr_spec_mdct_dmx, + FLOAT64 *ptr_spec_mdst_dmx, FLOAT64 *ptr_spec_mdct_mid_side, + FLOAT64 *ptr_spec_mdct_res) { + LOOPIDX i; + + for (i = 0; i < num_lines; i++) { + /* DMX = M; E = S - alpha*DMX if pred_dir = 0 */ + /* DMX = S; E = M - alpha*DMX if pred_dir = 1 */ + if (complex_coef == 1) { + ptr_spec_mdct_res[i] = + (FLOAT32)(ptr_spec_mdct_mid_side[i] - pred_coef_q_re * ptr_spec_mdct_dmx[i] - + pred_coef_q_im * ptr_spec_mdst_dmx[i]); + } else { + ptr_spec_mdct_res[i] = + (FLOAT32)(ptr_spec_mdct_mid_side[i] - pred_coef_q_re * ptr_spec_mdct_dmx[i]); + } + } +} + +static VOID iusace_filter_and_add(const FLOAT64 *ptr_in, const WORD32 length, + const FLOAT64 *ptr_filter, FLOAT64 *ptr_out, + const WORD32 factor_even) { + LOOPIDX i; + FLOAT64 s; + + i = 0; + s = ptr_filter[6] * ptr_in[2] + ptr_filter[5] * ptr_in[1] + ptr_filter[4] * ptr_in[0] + + ptr_filter[3] * ptr_in[0] + ptr_filter[2] * ptr_in[1] + ptr_filter[1] * ptr_in[2] + + ptr_filter[0] * ptr_in[3]; + ptr_out[i] += s * factor_even; + i = 1; + s = ptr_filter[6] * ptr_in[1] + ptr_filter[5] * ptr_in[0] + ptr_filter[4] * ptr_in[0] + + ptr_filter[3] * ptr_in[1] + ptr_filter[2] * ptr_in[2] + ptr_filter[1] * ptr_in[3] + + ptr_filter[0] * ptr_in[4]; + ptr_out[i] += s; + i = 2; + s = ptr_filter[6] * ptr_in[0] + ptr_filter[5] * ptr_in[0] + ptr_filter[4] * ptr_in[1] + + ptr_filter[3] * ptr_in[2] + ptr_filter[2] * ptr_in[3] + ptr_filter[1] * ptr_in[4] + + ptr_filter[0] * ptr_in[5]; + ptr_out[i] += s * factor_even; + + for (i = 3; i < length - 4; i += 2) { + s = ptr_filter[6] * ptr_in[i - 3] + ptr_filter[5] * ptr_in[i - 2] + + ptr_filter[4] * ptr_in[i - 1] + ptr_filter[3] * ptr_in[i] + + ptr_filter[2] * ptr_in[i + 1] + ptr_filter[1] * ptr_in[i + 2] + + ptr_filter[0] * ptr_in[i + 3]; + ptr_out[i] += s; + s = ptr_filter[6] * ptr_in[i - 2] + ptr_filter[5] * ptr_in[i - 1] + + ptr_filter[4] * ptr_in[i] + ptr_filter[3] * ptr_in[i + 1] + + ptr_filter[2] * ptr_in[i + 2] + ptr_filter[1] * ptr_in[i + 3] + + ptr_filter[0] * ptr_in[i + 4]; + ptr_out[i + 1] += s * factor_even; + } + + i = length - 3; + s = ptr_filter[6] * ptr_in[i - 3] + ptr_filter[5] * ptr_in[i - 2] + + ptr_filter[4] * ptr_in[i - 1] + ptr_filter[3] * ptr_in[i] + ptr_filter[2] * ptr_in[i + 1] + + ptr_filter[1] * ptr_in[i + 2] + ptr_filter[0] * ptr_in[i + 2]; + ptr_out[i] += s; + i = length - 2; + s = ptr_filter[6] * ptr_in[i - 3] + ptr_filter[5] * ptr_in[i - 2] + + ptr_filter[4] * ptr_in[i - 1] + ptr_filter[3] * ptr_in[i] + ptr_filter[2] * ptr_in[i + 1] + + ptr_filter[1] * ptr_in[i + 1] + ptr_filter[0] * ptr_in[i]; + ptr_out[i] += s * factor_even; + i = length - 1; + s = ptr_filter[6] * ptr_in[i - 3] + ptr_filter[5] * ptr_in[i - 2] + + ptr_filter[4] * ptr_in[i - 1] + ptr_filter[3] * ptr_in[i] + ptr_filter[2] * ptr_in[i] + + ptr_filter[1] * ptr_in[i - 1] + ptr_filter[0] * ptr_in[i - 2]; + ptr_out[i] += s; +} + +static VOID iusace_estimate_dmx_im(const FLOAT64 *ptr_dmx_re, const FLOAT64 *ptr_dmx_re_prev, + FLOAT64 *ptr_dmx_im, WORD32 window, const WORD32 w_shape, + const WORD32 prev_w_shape, WORD32 num_sbk, + WORD32 bins_per_sbk) { + LOOPIDX i; + const FLOAT64 *ptr_mdst_fcoeff_curr, *ptr_mdst_fcoeff_prev; + + switch (window) { + case ONLY_LONG_SEQUENCE: + case EIGHT_SHORT_SEQUENCE: + ptr_mdst_fcoeff_curr = iusace_mdst_fcoeff_longshort_curr[prev_w_shape][w_shape]; + ptr_mdst_fcoeff_prev = iusace_mdst_fcoeff_l_s_start_left_prev[prev_w_shape]; + break; + case LONG_START_SEQUENCE: + ptr_mdst_fcoeff_curr = iusace_mdst_fcoeff_start_curr[prev_w_shape][w_shape]; + ptr_mdst_fcoeff_prev = iusace_mdst_fcoeff_l_s_start_left_prev[prev_w_shape]; + break; + case LONG_STOP_SEQUENCE: + ptr_mdst_fcoeff_curr = iusace_mdst_fcoeff_stop_cur[prev_w_shape][w_shape]; + ptr_mdst_fcoeff_prev = iusace_mdst_fcoeff_stop_stopstart_left_prev[prev_w_shape]; + break; + case STOP_START_SEQUENCE: + ptr_mdst_fcoeff_curr = iusace_mdst_fcoeff_stopstart_cur[prev_w_shape][w_shape]; + ptr_mdst_fcoeff_prev = iusace_mdst_fcoeff_stop_stopstart_left_prev[prev_w_shape]; + break; + default: + ptr_mdst_fcoeff_curr = iusace_mdst_fcoeff_stopstart_cur[prev_w_shape][w_shape]; + ptr_mdst_fcoeff_prev = iusace_mdst_fcoeff_stop_stopstart_left_prev[prev_w_shape]; + break; + } + + for (i = 0; i < num_sbk; i++) { + iusace_filter_and_add(ptr_dmx_re, bins_per_sbk, ptr_mdst_fcoeff_curr, ptr_dmx_im, 1); + + if (ptr_dmx_re_prev) { + iusace_filter_and_add(ptr_dmx_re_prev, bins_per_sbk, ptr_mdst_fcoeff_prev, ptr_dmx_im, -1); + } + + ptr_dmx_re_prev = ptr_dmx_re; + ptr_dmx_re += bins_per_sbk; + ptr_dmx_im += bins_per_sbk; + } + return; +} + +static VOID iusace_usac_cplx_save_prev(FLOAT64 *ptr_mdct_spec, FLOAT64 *ptr_mdct_spec_prev, + WORD32 save_zeros, WORD32 condition_2, WORD32 samp_per_bk, + WORD32 bins_per_sbk) { + WORD32 offset; + + offset = samp_per_bk - bins_per_sbk; + + if (save_zeros || condition_2) { + memset(ptr_mdct_spec_prev + offset, 0, sizeof(FLOAT64) * bins_per_sbk); + } else { + memcpy(ptr_mdct_spec_prev + offset, ptr_mdct_spec + offset, sizeof(FLOAT64) * bins_per_sbk); + } + return; +} + +static FLOAT64 iusace_compute_ipd(FLOAT64 *ptr_spec_real1, FLOAT64 *ptr_spec_imag1, + FLOAT64 *ptr_spec_real2, FLOAT64 *ptr_spec_imag2, + WORD32 num_lines) { + LOOPIDX i; + + FLOAT64 ipd = 0.0f; + FLOAT64 cross_corr_real = 0.0f, cross_corr_imag = 0.0f; + + for (i = 0; i < num_lines; i++) { + cross_corr_real += + ptr_spec_real1[i] * ptr_spec_real2[i] + ptr_spec_imag1[i] * ptr_spec_imag2[i]; + cross_corr_imag += + -ptr_spec_imag2[i] * ptr_spec_real1[i] + ptr_spec_imag1[i] * ptr_spec_real2[i]; + } + + ipd = (FLOAT64)atan2(cross_corr_imag, cross_corr_real); + ipd = ipd > 0 ? ipd : 2. * PI + ipd; + + return ipd; +} + +static IA_ERRORCODE iusace_cplx_pred_main( + WORD32 num_sfb, WORD32 num_window_groups, FLOAT64 *ptr_spec_mdct_mid, + FLOAT64 *ptr_spec_mdct_side, WORD32 pred_coef_q_int_re[MAX_SHORT_WINDOWS][MAX_SFB_LONG], + WORD32 pred_coef_q_int_im[MAX_SHORT_WINDOWS][MAX_SFB_LONG], WORD32 *pred_dir, + ia_usac_data_struct *pstr_usac_data, ia_sfb_params_struct *pstr_sfb_prms, + WORD32 usac_independancy_flag, ia_usac_encoder_config_struct *pstr_usac_config, + FLOAT64 *ptr_scratch_cmpx_mdct_buf, WORD32 cplx_pred_used[MAX_SHORT_WINDOWS][MAX_SFB_LONG], + WORD32 chn, const WORD32 *ptr_sfb_offsets, FLOAT32 nrg_mid, FLOAT32 nrg_side, + WORD32 *ms_mask_flag) { + LOOPIDX group, sfb, i; + FLOAT32 pred_coef_re, pred_coef_im, pred_coef_q_re, pred_coef_q_im = 0.0f; + const WORD32 sfb_per_pred_band = 2; + WORD32 left = 0, right = 0, save_zeros = 0, condition_2 = 0, samp_per_bk = 0, bins_per_sbk = 0, + num_sbk = 0; + FLOAT64 *ptr_dmx_re_prev; + FLOAT64 *ptr_spec_mdct_res = &ptr_scratch_cmpx_mdct_buf[0]; + const WORD32 sfb_count = num_window_groups * num_sfb; + const WORD32 sfb_per_group = num_sfb; + WORD32 sfb_offsets = 0, zero_flag, spec_start, spec_end; + + left = chn, right = chn + 1; + + /* Number of sub-blocks */ + if (pstr_usac_config->window_sequence[left] == EIGHT_SHORT_SEQUENCE) { + num_sbk = MAX_SHORT_WINDOWS; + } + if (pstr_usac_config->window_sequence[left] == ONLY_LONG_SEQUENCE || + pstr_usac_config->window_sequence[left] == LONG_START_SEQUENCE || + pstr_usac_config->window_sequence[left] == LONG_STOP_SEQUENCE || + pstr_usac_config->window_sequence[left] == STOP_START_SEQUENCE) { + num_sbk = 1; + } + + if (num_sbk == 0) { + return IA_EXHEAACE_EXE_FATAL_USAC_INVALID_NUM_SBK; + } + + samp_per_bk = pstr_usac_config->ccfl; + bins_per_sbk = samp_per_bk / num_sbk; + + /* Compute prediction direction */ + if (nrg_mid >= nrg_side) { + *pred_dir = 0; + } else { + *pred_dir = 1; + } + + if (pstr_usac_data->complex_coef[chn] == 1) { + save_zeros = ((pstr_usac_config->window_sequence[left] == EIGHT_SHORT_SEQUENCE && + pstr_usac_config->window_sequence[right] != EIGHT_SHORT_SEQUENCE) || + (pstr_usac_config->window_sequence[left] != EIGHT_SHORT_SEQUENCE && + pstr_usac_config->window_sequence[right] == EIGHT_SHORT_SEQUENCE)); + + condition_2 = (usac_independancy_flag || pstr_usac_data->core_mode_prev[left] || + pstr_usac_data->core_mode_prev[right]); + + /* Compute current frame's MDST down-mix*/ + ptr_dmx_re_prev = !(usac_independancy_flag) ? pstr_usac_data->ptr_dmx_re_save[chn] : NULL; + + memset(pstr_usac_data->ptr_dmx_im[chn], 0, sizeof(FLOAT64) * FRAME_LEN_LONG); + + iusace_estimate_dmx_im(*pred_dir == 0 ? ptr_spec_mdct_mid : ptr_spec_mdct_side, + ptr_dmx_re_prev, pstr_usac_data->ptr_dmx_im[chn], + pstr_usac_config->window_sequence[left], + pstr_sfb_prms->window_shape[left], + pstr_usac_config->window_shape_prev[left], num_sbk, bins_per_sbk); + + /* MCLT of downmix = dmx_re + j*dmx_im */ + /* Save MDCT down-mix for use as previous frame MDCT down-mix in the next frame */ + iusace_usac_cplx_save_prev(*pred_dir == 0 ? &ptr_spec_mdct_mid[0] : &ptr_spec_mdct_side[0], + pstr_usac_data->ptr_dmx_re_save[chn], save_zeros, condition_2, + samp_per_bk, bins_per_sbk); + } + + /* Reset buffer to zero */ + for (group = 0; group < MAX_SHORT_WINDOWS; group++) { + memset(pred_coef_q_int_re, 0, MAX_SFB_LONG * sizeof(WORD32)); + memset(pred_coef_q_int_im, 0, MAX_SFB_LONG * sizeof(WORD32)); + } + + group = 0; + for (sfb = 0; sfb < sfb_count; sfb += sfb_per_group, group++) { + for (sfb_offsets = 0; sfb_offsets < sfb_per_group; sfb_offsets += sfb_per_pred_band) { + if (cplx_pred_used[group][sfb_offsets] == 1) { + zero_flag = (ptr_sfb_offsets[sfb + sfb_offsets + 1] != FRAME_LEN_LONG); + spec_start = ptr_sfb_offsets[sfb + sfb_offsets]; + spec_end = (zero_flag ? ptr_sfb_offsets[sfb + sfb_offsets + 2] + : ptr_sfb_offsets[sfb + sfb_offsets + 1]); + + /* Calculate prediction coefficients */ + iusace_compute_pred_coef( + spec_end - spec_start, pstr_usac_data->complex_coef[chn], + *pred_dir == 0 ? &ptr_spec_mdct_mid[spec_start] : &ptr_spec_mdct_side[spec_start], + pstr_usac_data->complex_coef[chn] == 1 ? &pstr_usac_data->ptr_dmx_im[chn][spec_start] + : NULL, + *pred_dir == 0 ? &ptr_spec_mdct_side[spec_start] : &ptr_spec_mdct_mid[spec_start], + &pred_coef_re, pstr_usac_data->complex_coef[chn] == 1 ? &pred_coef_im : NULL, + &pred_coef_q_re, pstr_usac_data->complex_coef[chn] == 1 ? &pred_coef_q_im : NULL, + &pred_coef_q_int_re[group][sfb_offsets], + pstr_usac_data->complex_coef[chn] == 1 ? &pred_coef_q_int_im[group][sfb_offsets] + : NULL); + + /* Calculate residual */ + iusace_compute_res( + spec_end - spec_start, pstr_usac_data->complex_coef[chn], pred_coef_q_re, + pstr_usac_data->complex_coef[chn] == 1 ? pred_coef_q_im : 0, + *pred_dir == 0 ? &ptr_spec_mdct_mid[spec_start] : &ptr_spec_mdct_side[spec_start], + pstr_usac_data->complex_coef[chn] == 1 ? &pstr_usac_data->ptr_dmx_im[chn][spec_start] + : NULL, + *pred_dir == 0 ? &ptr_spec_mdct_side[spec_start] : &ptr_spec_mdct_mid[spec_start], + &ptr_spec_mdct_res[spec_start]); + } + } + } + + /* Compute the prediction gain */ + FLOAT32 pred_gain = 0.f, nrg_res = 0.f; + for (i = 0; i < pstr_usac_config->ccfl; i++) { + nrg_res += (FLOAT32)(ptr_spec_mdct_res[i] * ptr_spec_mdct_res[i]); + } + pred_gain = + 10.f * log10f((*pred_dir == 0 ? nrg_side : nrg_mid) / nrg_res); /* Prediction gain in dB */ + + if (pred_gain > 20.f) /* Retain complex prediction */ + { + if (*pred_dir == 1) { + for (i = 0; i < pstr_usac_config->ccfl; i++) { + ptr_spec_mdct_mid[i] = ptr_spec_mdct_side[i]; + ptr_spec_mdct_side[i] = ptr_spec_mdct_res[i]; + } + } else { + for (i = 0; i < pstr_usac_config->ccfl; i++) { + ptr_spec_mdct_side[i] = ptr_spec_mdct_res[i]; + } + } + } else /* Use M/S */ + { + *ms_mask_flag = 0; + /* Revert spectra to L and R */ + for (i = 0; i < pstr_usac_config->ccfl; i++) { + ptr_spec_mdct_mid[i] = pstr_usac_data->left_chan_save[chn][i]; + ptr_spec_mdct_side[i] = pstr_usac_data->right_chan_save[chn][i]; + } + } + + return IA_NO_ERROR; +} + +IA_ERRORCODE iusace_cplx_pred_proc( + ia_usac_data_struct *pstr_usac_data, ia_usac_encoder_config_struct *pstr_usac_config, + WORD32 usac_independancy_flag, ia_sfb_params_struct *pstr_sfb_prms, WORD32 chn, + ia_psy_mod_data_struct *pstr_psy_data, const WORD32 *ptr_sfb_offsets, + FLOAT64 *ptr_scratch_cmpx_mdct_buf, FLOAT64 *ptr_ms_spec, FLOAT32 nrg_mid, FLOAT32 nrg_side) { + IA_ERRORCODE err_code; + FLOAT32 *ptr_sfb_enegry_left = pstr_psy_data[chn].ptr_sfb_energy_long; + FLOAT32 *ptr_sfb_energy_right = pstr_psy_data[chn + 1].ptr_sfb_energy_long; + const FLOAT32 *ptr_sfb_energy_mid = pstr_psy_data[chn].ptr_sfb_energy_long_ms; + const FLOAT32 *ptr_sfb_energy_side = pstr_psy_data[chn + 1].ptr_sfb_energy_long_ms; + FLOAT32 *ptr_sfb_thr_left = pstr_psy_data[chn].ptr_sfb_thr_long; + FLOAT32 *ptr_sfb_thr_right = pstr_psy_data[chn + 1].ptr_sfb_thr_long; + FLOAT32 *ptr_sfb_spread_energy_left = pstr_psy_data[chn].ptr_sfb_spreaded_energy_long; + FLOAT32 *ptr_sfb_spread_energy_right = pstr_psy_data[chn + 1].ptr_sfb_spreaded_energy_long; + WORD32 sfb, sfb_offsets; + WORD32 *ptr_num_sfb = pstr_sfb_prms->num_sfb; + WORD32 *ptr_num_window_groups = pstr_sfb_prms->num_window_groups; + const WORD32 sfb_count = ptr_num_window_groups[chn] * ptr_num_sfb[chn]; + const WORD32 sfb_per_group = ptr_num_sfb[chn]; + WORD32 grp = 0, i, zero_flag; + const WORD32 sfb_per_pred_band = 2; + FLOAT32 min_thr_1, min_thr_2 = 0.0f; + FLOAT32 temp_1 = 0, temp_2 = 0; + ia_ms_info_struct *pstr_ms_info = &pstr_usac_data->str_ms_info[chn]; + + FLOAT64 ipd; + /* Compute IPD between L and R channels */ + ipd = iusace_compute_ipd(&pstr_usac_data->spectral_line_vector[chn][0], + &pstr_usac_data->mdst_spectrum[chn][0], + &pstr_usac_data->spectral_line_vector[chn + 1][0], + &pstr_usac_data->mdst_spectrum[chn + 1][0], pstr_usac_config->ccfl); + + /* Decide value of complex_coef based on IPD */ + if ((ipd > (PI / 2 - 5 * PI / 180) && ipd < (PI / 2 + 5 * PI / 180)) || + (ipd > (3 * PI / 2 - 5 * PI / 180) && ipd < (3 * PI / 2 + 5 * PI / 180))) { + pstr_usac_data->complex_coef[chn] = 1; + } else { + pstr_usac_data->complex_coef[chn] = 0; + } + + /* Compute M and S spectra */ + for (i = 0; i < pstr_usac_config->ccfl; i++) { + pstr_usac_data->spectral_line_vector[chn][i] = ptr_ms_spec[i]; + pstr_usac_data->spectral_line_vector[chn + 1][i] = ptr_ms_spec[pstr_usac_config->ccfl + i]; + } + + err_code = iusace_cplx_pred_main( + pstr_sfb_prms->num_sfb[chn], pstr_sfb_prms->num_window_groups[chn], + pstr_usac_data->spectral_line_vector[chn], pstr_usac_data->spectral_line_vector[chn + 1], + pstr_usac_data->pred_coef_re[chn], pstr_usac_data->pred_coef_im[chn], + &pstr_usac_data->pred_dir_idx[chn], pstr_usac_data, pstr_sfb_prms, usac_independancy_flag, + pstr_usac_config, ptr_scratch_cmpx_mdct_buf, pstr_usac_data->cplx_pred_used[chn], chn, + ptr_sfb_offsets, nrg_mid, nrg_side, &pstr_ms_info->ms_mask); + if (err_code != IA_NO_ERROR) { + return err_code; + } + + if (pstr_ms_info->ms_mask == 3) { + /* Compute thresholds required for quantization (similar to that in MS coding) */ + for (sfb = 0; sfb < sfb_count; sfb += sfb_per_group, grp++) { + for (sfb_offsets = 0; sfb_offsets < sfb_per_group; sfb_offsets += sfb_per_pred_band) { + if (pstr_usac_data->cplx_pred_used[chn][grp][sfb_offsets] == 1) { + zero_flag = (ptr_sfb_offsets[sfb + sfb_offsets + 1] != pstr_usac_config->ccfl); + min_thr_1 = + MIN(ptr_sfb_thr_left[sfb + sfb_offsets], ptr_sfb_thr_right[sfb + sfb_offsets]); + if (zero_flag) { + min_thr_2 = MIN(ptr_sfb_thr_left[sfb + sfb_offsets + 1], + ptr_sfb_thr_right[sfb + sfb_offsets + 1]); + } + + ptr_sfb_thr_left[sfb + sfb_offsets] = ptr_sfb_thr_right[sfb + sfb_offsets] = min_thr_1; + ptr_sfb_enegry_left[sfb + sfb_offsets] = ptr_sfb_energy_mid[sfb + sfb_offsets]; + ptr_sfb_energy_right[sfb + sfb_offsets] = ptr_sfb_energy_side[sfb + sfb_offsets]; + if (zero_flag) { + ptr_sfb_thr_left[sfb + sfb_offsets + 1] = ptr_sfb_thr_right[sfb + sfb_offsets + 1] = + min_thr_2; + ptr_sfb_enegry_left[sfb + sfb_offsets + 1] = + ptr_sfb_energy_mid[sfb + sfb_offsets + 1]; + ptr_sfb_energy_right[sfb + sfb_offsets + 1] = + ptr_sfb_energy_side[sfb + sfb_offsets + 1]; + } + ptr_sfb_spread_energy_left[sfb + sfb_offsets] = + ptr_sfb_spread_energy_right[sfb + sfb_offsets] = + MIN(ptr_sfb_spread_energy_left[sfb + sfb_offsets], + ptr_sfb_spread_energy_right[sfb + sfb_offsets]) * + 0.5f; + if (zero_flag) { + ptr_sfb_spread_energy_left[sfb + sfb_offsets + 1] = + ptr_sfb_spread_energy_right[sfb + sfb_offsets + 1] = + MIN(ptr_sfb_spread_energy_left[sfb + sfb_offsets + 1], + ptr_sfb_spread_energy_right[sfb + sfb_offsets + 1]) * + 0.5f; + } + } + } + } + + if (pstr_usac_data->pred_dir_idx[chn] == 1) { + grp = 0; + + for (sfb = 0; sfb < sfb_count; sfb += sfb_per_group, grp++) { + for (sfb_offsets = 0; sfb_offsets < sfb_per_group; sfb_offsets += sfb_per_pred_band) { + zero_flag = (ptr_sfb_offsets[sfb + sfb_offsets + 1] != pstr_usac_config->ccfl); + + if (pstr_usac_data->cplx_pred_used[chn][grp][sfb_offsets] == 1) { + temp_1 = ptr_sfb_enegry_left[sfb + sfb_offsets]; + ptr_sfb_enegry_left[sfb + sfb_offsets] = ptr_sfb_energy_right[sfb + sfb_offsets]; + ptr_sfb_energy_right[sfb + sfb_offsets] = temp_1; + if (zero_flag) { + temp_2 = ptr_sfb_enegry_left[sfb + sfb_offsets + 1]; + ptr_sfb_enegry_left[sfb + sfb_offsets + 1] = + ptr_sfb_energy_right[sfb + sfb_offsets + 1]; + ptr_sfb_energy_right[sfb + sfb_offsets + 1] = temp_2; + } + } + } + } + } + } + return IA_NO_ERROR; +} diff --git a/encoder/ixheaace_cplx_pred.h b/encoder/ixheaace_cplx_pred.h new file mode 100644 index 0000000..5be087c --- /dev/null +++ b/encoder/ixheaace_cplx_pred.h @@ -0,0 +1,26 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +IA_ERRORCODE iusace_cplx_pred_proc( + ia_usac_data_struct *ptr_usac_data, ia_usac_encoder_config_struct *ptr_usac_config, + WORD32 usac_independancy_flag, ia_sfb_params_struct *pstr_sfb_prms, WORD32 chn, + ia_psy_mod_data_struct *pstr_psy_data, const WORD32 *ptr_sfb_offsets, + FLOAT64 *scratch_cmpx_mdct_temp_buf, FLOAT64 *ptr_ms_spec, FLOAT32 nrg_mid, FLOAT32 nrg_side); diff --git a/encoder/ixheaace_dynamic_bits.c b/encoder/ixheaace_dynamic_bits.c index a87a77f..c268300 100644 --- a/encoder/ixheaace_dynamic_bits.c +++ b/encoder/ixheaace_dynamic_bits.c @@ -20,14 +20,18 @@ #include #include +#include +#include #include "ixheaac_type_def.h" #include "ixheaac_constants.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" #include "ixheaace_api.h" #include "ixheaace_aac_constants.h" #include "ixheaac_error_standards.h" #include "ixheaace_error_codes.h" -#include -#include #include "ixheaac_basic_ops32.h" #include "ixheaac_basic_ops16.h" diff --git a/encoder/ixheaace_enc_init.c b/encoder/ixheaace_enc_init.c index 3c94b6d..932877e 100644 --- a/encoder/ixheaace_enc_init.c +++ b/encoder/ixheaace_enc_init.c @@ -22,6 +22,10 @@ #include "ixheaac_type_def.h" #include "ixheaac_constants.h" #include "ixheaace_aac_constants.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" #include "ixheaace_api.h" #include "ixheaac_error_standards.h" #include "ixheaace_error_codes.h" diff --git a/encoder/ixheaace_enc_main.c b/encoder/ixheaace_enc_main.c index 8eac852..3e813fe 100644 --- a/encoder/ixheaace_enc_main.c +++ b/encoder/ixheaace_enc_main.c @@ -19,12 +19,15 @@ */ #include - +#include #include "ixheaac_type_def.h" #include "ixheaac_constants.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" #include "ixheaace_api.h" #include "ixheaace_aac_constants.h" -#include #include "ixheaac_basic_ops32.h" #include "ixheaac_basic_ops16.h" #include "ixheaac_basic_ops40.h" diff --git a/encoder/ixheaace_error_codes.h b/encoder/ixheaace_error_codes.h index 3925e9d..8065efe 100644 --- a/encoder/ixheaace_error_codes.h +++ b/encoder/ixheaace_error_codes.h @@ -67,7 +67,7 @@ // USAC // DRC - +#define IA_EXHEAACE_CONFIG_NONFATAL_DRC_MISSING_CONFIG (0x00000B00) /* Fatal Errors */ // AAC profiles @@ -87,9 +87,14 @@ // MPS // USAC +#define IA_EXHEAACE_CONFIG_FATAL_USAC_SAMP_FREQ (0xFFFF8A00) +#define IA_EXHEAACE_CONFIG_FATAL_USAC_RESAMPLER_RATIO (0xFFFF8A01) // DRC - +#define IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG (0xFFFF8B00) +#define IA_EXHEAACE_CONFIG_FATAL_DRC_UNSUPPORTED_CONFIG (0xFFFF8B01) +#define IA_EXHEAACE_CONFIG_FATAL_DRC_PARAM_OUT_OF_RANGE (0xFFFF8B02) +#define IA_EXHEAACE_CONFIG_FATAL_DRC_COMPAND_FAILED (0xFFFF8B03) /*****************************************************************************/ /* Class 2: Initialization Errors */ /*****************************************************************************/ @@ -113,7 +118,10 @@ // MPS #define IA_EXHEAACE_INIT_FATAL_MPS_INIT_FAILED (0xFFFF9100) + // USAC +#define IA_EXHEAACE_INIT_FATAL_USAC_RESAMPLER_INIT_FAILED (0xFFFF9200) +#define IA_EXHEAACE_INIT_FATAL_USAC_BITRES_SIZE_TOO_SMALL (0xFFFF9201) // DRC @@ -140,13 +148,13 @@ // DRC // ESBR -#define IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_BANDWIDTH_INDEX (0x0001C00) -#define IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_NUM_PATCH (0x0001C01) -#define IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_VOCOD_BUF (0x0001C02) -#define IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_PVC_MODE (0x0001C03) -#define IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_FFT (0x0001C04) -#define IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_START_BAND (0x0001C05) -#define IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_VALUE (0x0001C06) +#define IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_BANDWIDTH_INDEX (0x00001C00) +#define IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_NUM_PATCH (0x00001C01) +#define IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_VOCOD_BUF (0x00001C02) +#define IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_PVC_MODE (0x00001C03) +#define IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_FFT (0x00001C04) +#define IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_START_BAND (0x00001C05) +#define IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_VALUE (0x00001C06) /* Fatal Errors */ @@ -167,7 +175,7 @@ #define IA_EXHEAACE_EXE_FATAL_INVALID_SIDE_INFO_BITS (0xFFFF980D) #define IA_EXHEAACE_EXE_FATAL_INVALID_HUFFMAN_BITS (0xFFFF980E) #define IA_EXHEAACE_EXE_FATAL_INVALID_SCALE_FACTOR_BITS (0xFFFF980F) -#define IA_EXHAACE_EXE_FATAL_SBR_INVALID_AMP_RES (0xFFFF9810) +#define IA_EXHEAACE_EXE_FATAL_SBR_INVALID_AMP_RES (0xFFFF9810) #define IA_EXHEAACE_EXE_FATAL_INVALID_OUT_BYTES (0xFFFF9811) #define IA_EXHEAACE_EXE_FATAL_INVALID_TNS_FILT_ORDER (0xFFFF9812) #define IA_EXHEAACE_EXE_FATAL_SBR_INVALID_SAMP_FREQ (0xFFFF9813) @@ -187,5 +195,9 @@ #define IA_EXHEAACE_EXE_FATAL_MPS_CFFT_PROCESS (0xFFFF990B) // USAC - +#define IA_EXHEAACE_EXE_FATAL_USAC_INVALID_FAC_LEN (0xFFFF9A00) +#define IA_EXHEAACE_EXE_FATAL_USAC_INVALID_NUM_SBK (0xFFFF9A01) +#define IA_EXHEAACE_EXE_FATAL_USAC_INVALID_NUM_CHANNEL (0xFFFF9A02) +#define IA_EXHEAACE_EXE_FATAL_USAC_INVALID_BIT_RSVR_LVL (0xFFFF9A03) +#define IA_EXHEAACE_EXE_FATAL_USAC_INVALID_MAPPING (0xFFFF9A04) // DRC diff --git a/encoder/ixheaace_fd_enc.c b/encoder/ixheaace_fd_enc.c new file mode 100644 index 0000000..e5d846a --- /dev/null +++ b/encoder/ixheaace_fd_enc.c @@ -0,0 +1,133 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include "iusace_type_def.h" +#include "iusace_bitbuffer.h" +#include "iusace_cnst.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_api.h" +#include "impd_drc_uni_drc_eq.h" +#include "impd_drc_uni_drc_filter_bank.h" +#include "impd_drc_gain_enc.h" +#include "impd_drc_struct_def.h" + +#include "ixheaace_memory_standards.h" +#include "iusace_tns_usac.h" +#include "iusace_psy_mod.h" +#include "iusace_config.h" +#include "ixheaace_adjust_threshold_data.h" +#include "iusace_fd_qc_util.h" +#include "iusace_config.h" +#include "iusace_arith_enc.h" +#include "iusace_fd_quant.h" +#include "iusace_ms.h" +#include "iusace_signal_classifier.h" +#include "iusace_block_switch_const.h" +#include "iusace_block_switch_struct_def.h" +#include "ixheaace_sbr_header.h" +#include "ixheaace_config.h" +#include "ixheaace_asc_write.h" +#include "iusace_main.h" +#include "iusace_write_bitstream.h" +#include "iusace_lpd.h" +#include "ixheaace_cplx_pred.h" +#include "iusace_func_prototypes.h" + +#if DEBUG_DUMP +extern FILE *out_file; +#endif + +IA_ERRORCODE iusace_fd_encode(ia_sfb_params_struct *pstr_sfb_prms, WORD32 usac_independancy_flag, + ia_usac_data_struct *pstr_usac_data, + ia_usac_encoder_config_struct *pstr_usac_config, + ia_bit_buf_struct *pstr_it_bit_buff, WORD32 nr_core_coder_ch, + WORD32 chn, WORD32 ele_id, WORD32 *bit_written) { + iusace_scratch_mem *pstr_scratch = &pstr_usac_data->str_scratch; + IA_ERRORCODE err_code = 0; + WORD32 i_ch, idx = 0; + WORD32 *ptr_num_fac_bits = pstr_scratch->ptr_num_fac_bits; + WORD32 tns_data_present[2] = {0}; + WORD32 *ptr_core_mode_next = pstr_usac_data->core_mode_next; + WORD32 *ptr_core_mode_prev = pstr_usac_data->core_mode_prev; + *bit_written = 0; + memset(pstr_scratch->ptr_num_fac_bits, 0, + MAX_TIME_CHANNELS * sizeof(pstr_scratch->ptr_num_fac_bits[0])); + for (i_ch = chn; i_ch < chn + nr_core_coder_ch; i_ch++) { + tns_data_present[idx] = pstr_usac_data->pstr_tns_info[i_ch] != NULL; + + if (tns_data_present[idx]) { + tns_data_present[idx] = pstr_usac_data->pstr_tns_info[i_ch]->tns_data_present; + } + idx++; + } + + idx = 0; + for (i_ch = chn; i_ch < chn + nr_core_coder_ch; i_ch++) { + memset(pstr_scratch->p_reconstructed_time_signal[idx], 0, 4096 * sizeof(FLOAT64)); + err_code = iusace_fd_fac( + pstr_sfb_prms->grouped_sfb_offset[i_ch], pstr_sfb_prms->max_sfb[i_ch], + pstr_usac_data->ptr_2frame_time_data[i_ch], pstr_sfb_prms->window_sequence[i_ch], + pstr_scratch->p_reconstructed_time_signal[idx], pstr_usac_data->td_encoder[i_ch], + ((pstr_usac_data->td_encoder[i_ch]->prev_mode == 0) && ptr_core_mode_prev[i_ch]) == + CORE_MODE_TD, + ptr_core_mode_next[i_ch] == CORE_MODE_TD, pstr_usac_data->fac_out_stream[i_ch], + &ptr_num_fac_bits[i_ch], pstr_scratch); + if (err_code) { + return err_code; + } + idx++; + } + + err_code = iusace_quantize_spec(pstr_sfb_prms, usac_independancy_flag, nr_core_coder_ch, + pstr_usac_data, pstr_usac_config, chn, ele_id); + if (err_code) return err_code; + + for (i_ch = chn; i_ch < chn + nr_core_coder_ch; i_ch++) { + pstr_sfb_prms->window_shape[i_ch] = + pstr_usac_data->str_psy_mod.str_psy_out_data[i_ch].window_shape; + } + + if (nr_core_coder_ch == 1) { + iusace_write_bits_buf(pstr_it_bit_buff, tns_data_present[0], 1); + *bit_written = *bit_written + 1; + } + if (nr_core_coder_ch == 2) { + *bit_written = *bit_written + iusace_write_cpe(pstr_sfb_prms, pstr_it_bit_buff, + tns_data_present, usac_independancy_flag, + pstr_usac_config, pstr_usac_data, chn); + } + +#if DEBUG_DUMP + fprintf(out_file, "%d\t", *bit_written); +#endif + + idx = 0; + for (i_ch = chn; i_ch < chn + nr_core_coder_ch; i_ch++) { + *bit_written = + *bit_written + iusace_write_fd_data(pstr_it_bit_buff, pstr_sfb_prms, + ptr_num_fac_bits[i_ch], usac_independancy_flag, + pstr_usac_data, pstr_usac_config, i_ch, ele_id, idx); + idx++; + } + + return err_code; +} diff --git a/encoder/ixheaace_fd_mdct.c b/encoder/ixheaace_fd_mdct.c new file mode 100644 index 0000000..2ef6b74 --- /dev/null +++ b/encoder/ixheaace_fd_mdct.c @@ -0,0 +1,214 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include "iusace_type_def.h" + +#include "ixheaace_mps_common_define.h" +#include "iusace_cnst.h" +#include "iusace_bitbuffer.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_api.h" +#include "impd_drc_uni_drc_eq.h" +#include "impd_drc_uni_drc_filter_bank.h" +#include "impd_drc_gain_enc.h" +#include "impd_drc_struct_def.h" + +#include "iusace_cnst.h" +#include "iusace_tns_usac.h" +#include "iusace_psy_mod.h" +#include "iusace_ms.h" + +#include "ixheaace_adjust_threshold_data.h" +#include "iusace_fd_qc_util.h" +#include "ixheaace_memory_standards.h" +#include "iusace_config.h" +#include "iusace_fft.h" +#include "iusace_arith_enc.h" +#include "iusace_fd_quant.h" +#include "iusace_signal_classifier.h" +#include "iusace_block_switch_const.h" +#include "iusace_block_switch_struct_def.h" +#include "ixheaace_sbr_header.h" +#include "ixheaace_config.h" +#include "ixheaace_asc_write.h" +#include "iusace_main.h" +#include "iusace_windowing.h" + +static IA_ERRORCODE iusace_fd_mdct_short(ia_usac_data_struct *pstr_usac_data, + ia_usac_encoder_config_struct *pstr_usac_config, + WORD32 ch_idx) { + IA_ERRORCODE err_code = 0; + iusace_scratch_mem *pstr_scratch = &pstr_usac_data->str_scratch; + IA_ERRORCODE err_code_2 = 0; + FLOAT64 *ptr_windowed_buf = pstr_scratch->p_fd_mdct_windowed_short_buf; + WORD32 n_long = pstr_usac_config->ccfl; + WORD32 n_short = pstr_usac_config->ccfl >> 3; + FLOAT64 *ptr_in_data = pstr_usac_data->ptr_time_data[ch_idx]; + FLOAT64 *ptr_out_mdct = pstr_usac_data->spectral_line_vector[ch_idx]; + FLOAT64 *ptr_out_mdst = pstr_usac_data->mdst_spectrum[ch_idx]; + WORD32 window_shape = pstr_usac_config->window_shape_prev[ch_idx]; + FLOAT64 *ptr_win_gen_medium = NULL, *ptr_win_gen_short = NULL; + FLOAT64 *ptr_overlap = pstr_usac_data->overlap_buf[ch_idx]; + WORD32 nflat_ls; + WORD32 i, k; + WORD32 data_size = (OVERLAP_WIN_SIZE_576 * n_long) / LEN_SUPERFRAME; + + memset(ptr_windowed_buf, 0, 2 * n_short * sizeof(FLOAT64)); + nflat_ls = (n_long - n_short) >> 1; + err_code = iusace_calc_window(&ptr_win_gen_short, n_short, window_shape); + if (err_code) return err_code; + err_code = iusace_calc_window(&ptr_win_gen_medium, n_short, 0); + if (err_code) return err_code; + ptr_overlap += nflat_ls; + + for (k = MAX_SHORT_WINDOWS - 1; k-- >= 0;) { + for (i = 0; i < n_short; i++) { + ptr_windowed_buf[i] = ptr_win_gen_short[i] * ptr_overlap[i]; + } + for (i = 0; i < n_short; i++) { + ptr_windowed_buf[i + n_short] = + ptr_win_gen_medium[n_short - 1 - i] * ptr_overlap[i + n_short]; + } + + ptr_win_gen_medium = ptr_win_gen_short; + + // Compute MDCT + err_code = iusace_fft_based_mdct(ptr_windowed_buf, ptr_out_mdct, n_short, MDCT_TX_FLAG, + pstr_scratch); + + if (err_code) { + return err_code; + } + + // Compute MDST + err_code_2 = iusace_fft_based_mdct(ptr_windowed_buf, ptr_out_mdst, n_short, MDST_TX_FLAG, + pstr_scratch); + + if (err_code_2) { + return err_code_2; + } + + ptr_out_mdct += n_short; + ptr_out_mdst += n_short; + ptr_overlap += n_short; + } + + ptr_overlap = pstr_usac_data->overlap_buf[ch_idx]; + memcpy(ptr_overlap, ptr_overlap + n_long, data_size * sizeof(*ptr_overlap)); + memcpy(ptr_overlap + data_size, ptr_in_data, n_long * sizeof(*ptr_overlap)); + + return err_code; +} + +static IA_ERRORCODE iusace_fd_mdct_long(ia_usac_data_struct *pstr_usac_data, + ia_usac_encoder_config_struct *pstr_usac_config, + WORD32 ch_idx, WORD32 window_sequence) { + IA_ERRORCODE err_code = 0; + iusace_scratch_mem *pstr_scratch = &pstr_usac_data->str_scratch; + IA_ERRORCODE err_code_2 = 0; + FLOAT64 *ptr_windowed_buf = pstr_scratch->p_fd_mdct_windowed_long_buf; + WORD32 n_long = pstr_usac_config->ccfl; + WORD32 n_short = pstr_usac_config->ccfl >> 3; + WORD32 prev_mode = (pstr_usac_data->core_mode_prev[ch_idx] == CORE_MODE_TD); + WORD32 next_mode = (pstr_usac_data->core_mode_next[ch_idx] == CORE_MODE_TD); + FLOAT64 *ptr_in_data = pstr_usac_data->ptr_time_data[ch_idx]; + FLOAT64 *ptr_out_mdct = pstr_usac_data->spectral_line_vector[ch_idx]; + FLOAT64 *ptr_out_mdst = pstr_usac_data->mdst_spectrum[ch_idx]; + WORD32 window_shape = pstr_usac_config->window_shape_prev[ch_idx]; + FLOAT64 *ptr_win_long = NULL, *ptr_win_med = NULL; + WORD32 win_len; + FLOAT64 *ptr_overlap = pstr_usac_data->overlap_buf[ch_idx]; + + WORD32 nflat_ls; + + memset(ptr_windowed_buf, 0, 2 * n_long * sizeof(*ptr_windowed_buf)); + + switch (window_sequence) { + case ONLY_LONG_SEQUENCE: + err_code = iusace_calc_window(&ptr_win_long, n_long, window_shape); + if (err_code) return err_code; + iusace_windowing_long(ptr_overlap, ptr_win_long, ptr_windowed_buf, ptr_in_data, n_long); + break; + + case LONG_START_SEQUENCE: + win_len = n_short << next_mode; + nflat_ls = (n_long - win_len) >> 1; + err_code = iusace_calc_window(&ptr_win_long, n_long, window_shape); + if (err_code) return err_code; + err_code = iusace_calc_window(&ptr_win_med, win_len, 0); + if (err_code) return err_code; + + iusace_windowing_long_start(ptr_overlap, ptr_win_long, ptr_windowed_buf, ptr_in_data, + n_long, nflat_ls, ptr_win_med, win_len); + break; + + case LONG_STOP_SEQUENCE: + win_len = n_short << prev_mode; + nflat_ls = (n_long - win_len) >> 1; + err_code = iusace_calc_window(&ptr_win_long, n_long, window_shape); + if (err_code) return err_code; + err_code = iusace_calc_window(&ptr_win_med, win_len, 1); + if (err_code) return err_code; + iusace_windowing_long_stop(ptr_overlap, ptr_win_long, ptr_windowed_buf, ptr_in_data, n_long, + nflat_ls, ptr_win_med, win_len); + break; + + case STOP_START_SEQUENCE: + win_len = n_short << (prev_mode | next_mode); + err_code = iusace_calc_window(&ptr_win_med, win_len, window_shape); + if (err_code) return err_code; + + iusace_windowing_stop_start(ptr_overlap, ptr_windowed_buf, ptr_win_med, win_len, n_long); + break; + } + + // Compute MDCT + err_code = + iusace_fft_based_mdct(ptr_windowed_buf, ptr_out_mdct, n_long, MDCT_TX_FLAG, pstr_scratch); + if (err_code) { + return err_code; + } + + // Compute MDST + err_code_2 = + iusace_fft_based_mdct(ptr_windowed_buf, ptr_out_mdst, n_long, MDST_TX_FLAG, pstr_scratch); + + if (err_code_2) { + return err_code_2; + } + + return 0; +} + +WORD32 iusace_fd_mdct(ia_usac_data_struct *pstr_usac_data, + ia_usac_encoder_config_struct *pstr_usac_config, WORD32 ch_idx) { + IA_ERRORCODE err_code = 0; + WORD32 window_sequence = pstr_usac_config->window_sequence[ch_idx]; + + if (window_sequence != EIGHT_SHORT_SEQUENCE) { + err_code = iusace_fd_mdct_long(pstr_usac_data, pstr_usac_config, ch_idx, window_sequence); + } else { + err_code = iusace_fd_mdct_short(pstr_usac_data, pstr_usac_config, ch_idx); + } + + return err_code; +} diff --git a/encoder/ixheaace_fd_qc_adjthr.c b/encoder/ixheaace_fd_qc_adjthr.c new file mode 100644 index 0000000..3338a78 --- /dev/null +++ b/encoder/ixheaace_fd_qc_adjthr.c @@ -0,0 +1,1698 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include +#include +#include +#include "iusace_type_def.h" +#include "ixheaac_error_standards.h" +#include "ixheaace_error_codes.h" +#include "ixheaace_psy_const.h" +#include "ixheaace_tns.h" +#include "ixheaace_tns_params.h" +#include "ixheaace_rom.h" +#include "iusace_block_switch_const.h" +#include "iusace_cnst.h" +#include "iusace_rom.h" +#include "ixheaace_mps_common_define.h" +#include "iusace_bitbuffer.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_api.h" +#include "impd_drc_uni_drc_eq.h" +#include "impd_drc_uni_drc_filter_bank.h" +#include "impd_drc_gain_enc.h" +#include "impd_drc_struct_def.h" + +#include "ixheaace_memory_standards.h" +#include "iusace_tns_usac.h" +#include "iusace_psy_mod.h" +#include "iusace_config.h" +#include "ixheaace_adjust_threshold_data.h" +#include "iusace_fd_qc_util.h" +#include "iusace_fd_qc_adjthr.h" +#include "ixheaace_aac_constants.h" + +FLOAT32 iusace_bits_to_pe(const FLOAT32 bits) { return (bits * 1.18f); } + +VOID iusace_adj_thr_init(ia_adj_thr_elem_struct *pstr_adj_thr_ele, const FLOAT32 mean_pe, + WORD32 ch_bitrate) { + ia_min_snr_adapt_param_struct *pstr_min_snr_params = + &pstr_adj_thr_ele->str_min_snr_adapt_params; + + pstr_adj_thr_ele->pe_min = (FLOAT32)0.8f * mean_pe; + pstr_adj_thr_ele->pe_max = (FLOAT32)1.2f * mean_pe; + pstr_adj_thr_ele->pe_offset = 0.0f; + + if (ch_bitrate < 32000) { + pstr_adj_thr_ele->pe_offset = + MAX((FLOAT32)50.0f, (FLOAT32)(100.0f) - (FLOAT32)(100.0f / 32000) * (FLOAT32)ch_bitrate); + } + + if (ch_bitrate > 20000) { + pstr_adj_thr_ele->str_ah_param.modify_min_snr = TRUE; + pstr_adj_thr_ele->str_ah_param.start_sfb_long = 15; + pstr_adj_thr_ele->str_ah_param.start_sfb_short = 3; + } else { + pstr_adj_thr_ele->str_ah_param.modify_min_snr = FALSE; + pstr_adj_thr_ele->str_ah_param.start_sfb_long = 0; + pstr_adj_thr_ele->str_ah_param.start_sfb_short = 0; + } + + pstr_min_snr_params->max_red = (FLOAT32)0.25f; + + pstr_min_snr_params->start_ratio = (FLOAT32)10.0f; + + pstr_min_snr_params->max_ratio = (FLOAT32)1000.0f; + + pstr_min_snr_params->red_ratio_fac = + (1.0f - pstr_min_snr_params->max_red) / + (10.0f * (FLOAT32)log10(pstr_min_snr_params->start_ratio / pstr_min_snr_params->max_ratio)); + + pstr_min_snr_params->red_offs = 1.0f - pstr_min_snr_params->red_ratio_fac * 10.0f * + (FLOAT32)log10(pstr_min_snr_params->start_ratio); + + pstr_adj_thr_ele->pe_last = (FLOAT32)0.0f; + pstr_adj_thr_ele->dyn_bits_last = 0; + pstr_adj_thr_ele->pe_correction_fac = (FLOAT32)1.0f; +} + +static VOID iusace_calc_sfb_pe_data(ia_qc_pe_data_struct *pstr_qc_pe_data, + ia_psy_mod_out_data_struct *pstr_psy_out, WORD32 num_channels, + WORD32 chn) { + WORD32 ch, idx = 0; + WORD32 scf_band_grp; + FLOAT32 num_lines; + FLOAT32 ld_thr, ld_ratio; + WORD32 i = 0, scf; + WORD32 sfb_count; + WORD32 scf_band_per_grp; + WORD32 max_sfb_per_grp; + FLOAT32 *ptr_sfb_energy; + FLOAT32 *ptr_sfb_thr; + ia_qc_pe_chan_data_struct *str_qc_pe_chan_data; + + pstr_qc_pe_data->pe = pstr_qc_pe_data->offset; + pstr_qc_pe_data->const_part = 0.0f; + pstr_qc_pe_data->num_active_lines = 0.0f; + + for (ch = chn; ch < chn + num_channels; ch++) { + sfb_count = pstr_psy_out[ch].sfb_count; + scf_band_per_grp = pstr_psy_out[ch].sfb_per_group; + max_sfb_per_grp = pstr_psy_out[ch].max_sfb_per_grp; + ptr_sfb_energy = pstr_psy_out[ch].ptr_sfb_energy; + ptr_sfb_thr = pstr_psy_out[ch].ptr_sfb_thr; + str_qc_pe_chan_data = &pstr_qc_pe_data->pe_ch_data[idx]; + str_qc_pe_chan_data->pe = 0; + str_qc_pe_chan_data->num_active_lines = 0; + str_qc_pe_chan_data->const_part = 0; + + for (scf_band_grp = 0; scf_band_grp < sfb_count; scf_band_grp += scf_band_per_grp) { + i = scf_band_grp; + for (scf = max_sfb_per_grp - 1; scf >= 0; scf--, i++) { + if (ptr_sfb_energy[i] > ptr_sfb_thr[i]) { + ld_thr = (FLOAT32)log(ptr_sfb_thr[i]) * LOG2_1; + ld_ratio = str_qc_pe_chan_data->sfb_ld_energy[i] - ld_thr; + num_lines = str_qc_pe_chan_data->sfb_lines[i]; + if (ld_ratio >= PE_C1) { + str_qc_pe_chan_data->sfb_pe[i] = num_lines * ld_ratio; + str_qc_pe_chan_data->sfb_const_part[i] = + num_lines * str_qc_pe_chan_data->sfb_ld_energy[i]; + } else { + str_qc_pe_chan_data->sfb_pe[i] = num_lines * (PE_C2 + PE_C3 * ld_ratio); + str_qc_pe_chan_data->sfb_const_part[i] = + num_lines * (PE_C2 + PE_C3 * str_qc_pe_chan_data->sfb_ld_energy[i]); + num_lines = num_lines * PE_C3; + } + str_qc_pe_chan_data->num_sfb_active_lines[i] = num_lines; + } else { + str_qc_pe_chan_data->sfb_pe[i] = 0.0f; + str_qc_pe_chan_data->sfb_const_part[i] = 0.0f; + str_qc_pe_chan_data->num_sfb_active_lines[i] = 0.0; + } + + str_qc_pe_chan_data->pe += str_qc_pe_chan_data->sfb_pe[i]; + str_qc_pe_chan_data->const_part += str_qc_pe_chan_data->sfb_const_part[i]; + str_qc_pe_chan_data->num_active_lines += str_qc_pe_chan_data->num_sfb_active_lines[i]; + } + } + pstr_qc_pe_data->pe += str_qc_pe_chan_data->pe; + pstr_qc_pe_data->const_part += str_qc_pe_chan_data->const_part; + pstr_qc_pe_data->num_active_lines += str_qc_pe_chan_data->num_active_lines; + pstr_psy_out[ch].pe = pstr_qc_pe_data->pe; + idx++; + } + return; +} + +static VOID iusace_adj_pe_minmax(const FLOAT32 curr_pe, FLOAT32 *pe_min, FLOAT32 *pe_max) { + FLOAT32 min_hi_fac = 0.3f, max_hi_fac = 1.0f, min_low_fac = 0.14f, max_low_fac = 0.07f; + FLOAT32 diff; + FLOAT32 min_diff = curr_pe * (FLOAT32)0.1666666667f; + + if (curr_pe > *pe_max) { + diff = (curr_pe - *pe_max); + *pe_min += diff * min_hi_fac; + *pe_max += diff * max_hi_fac; + } else { + if (curr_pe < *pe_min) { + diff = (*pe_min - curr_pe); + *pe_min -= diff * min_low_fac; + *pe_max -= diff * max_low_fac; + } else { + *pe_min += (curr_pe - *pe_min) * min_hi_fac; + *pe_max -= (*pe_max - curr_pe) * max_low_fac; + } + } + + if ((*pe_max - *pe_min) < min_diff) { + FLOAT32 low_part, high_part; + low_part = MAX((FLOAT32)0.0f, curr_pe - *pe_min); + high_part = MAX((FLOAT32)0.0f, *pe_max - curr_pe); + *pe_max = curr_pe + high_part / (low_part + high_part) * min_diff; + *pe_min = curr_pe - low_part / (low_part + high_part) * min_diff; + *pe_min = MAX((FLOAT32)0.0f, *pe_min); + } + + return; +} + +static FLOAT32 iusace_bitres_calc_bitfac(const WORD32 bitres_bits, const WORD32 max_bitres_bits, + const FLOAT32 pe, const WORD32 win_seq, + const WORD32 avg_bits, const FLOAT32 max_bit_fac, + ia_adj_thr_elem_struct *pstr_adj_thr_elem) { + FLOAT32 pex; + FLOAT32 fill_lvl; + FLOAT32 bit_save, bit_spend, bitres_factor; + + fill_lvl = (FLOAT32)bitres_bits / (FLOAT32)max_bitres_bits; + + if (win_seq != EIGHT_SHORT_SEQUENCE) { + fill_lvl = MAX(fill_lvl, CLIP_SAVE_LO_LONG); + fill_lvl = MIN(fill_lvl, CLIP_SAVE_HI_LONG); + bit_save = MAX_BITS_SAVE_LONG - (BITS_SAVE_RATIO_LONG * (fill_lvl - CLIP_SAVE_LO_LONG)); + bit_spend = MIN_BITS_SPEND_LONG + (BITS_SPEND_RATIO_LONG * (fill_lvl - CLIP_SPEND_LO_LONG)); + } else { + fill_lvl = MAX(fill_lvl, CLIP_SPEND_LO_SHORT); + fill_lvl = MIN(fill_lvl, CLIP_SPEND_HI_SHORT); + bit_save = MAX_BITS_SAVE_SHORT - (BITS_SAVE_RATIO_SHORT * (fill_lvl - CLIP_SAVE_LO_SHORT)); + bit_spend = + MIN_BITS_SPEND_SHORT + (BITS_SPEND_RATIO_SHORT * (fill_lvl - CLIP_SPEND_LO_SHORT)); + } + + pex = MAX(pe, pstr_adj_thr_elem->pe_min); + pex = MIN(pex, pstr_adj_thr_elem->pe_max); + + bitres_factor = + (FLOAT32)1.0f - bit_save + + ((bit_spend + bit_save) / (pstr_adj_thr_elem->pe_max - pstr_adj_thr_elem->pe_min)) * + (pex - pstr_adj_thr_elem->pe_min); + bitres_factor = MIN(bitres_factor, + (FLOAT32)1.0f - (FLOAT32)0.3f + (FLOAT32)bitres_bits / (FLOAT32)avg_bits); + + bitres_factor = MIN(bitres_factor, max_bit_fac); + iusace_adj_pe_minmax(pe, &pstr_adj_thr_elem->pe_min, &pstr_adj_thr_elem->pe_max); + + return bitres_factor; +} + +static VOID iusace_calc_pe_correction(FLOAT32 *correction_fac, const FLOAT32 pe_act, + const FLOAT32 pe_last, const WORD32 bits_prev) { + if ((bits_prev > 0) && (pe_act < (FLOAT32)1.5f * pe_last) && + (pe_act > (FLOAT32)0.7f * pe_last) && + ((FLOAT32)1.2f * iusace_bits_to_pe((FLOAT32)bits_prev) > pe_last) && + ((FLOAT32)0.65f * iusace_bits_to_pe((FLOAT32)bits_prev) < pe_last)) { + FLOAT32 new_fac = pe_last / iusace_bits_to_pe((FLOAT32)bits_prev); + + if (new_fac < (FLOAT32)1.0f) { + new_fac = MIN((FLOAT32)1.1f * new_fac, (FLOAT32)1.0f); + new_fac = MAX(new_fac, (FLOAT32)0.85f); + } else { + new_fac = MAX((FLOAT32)0.9f * new_fac, (FLOAT32)1.0f); + new_fac = MIN(new_fac, (FLOAT32)1.15f); + } + if (((new_fac > (FLOAT32)1.0f) && (*correction_fac < (FLOAT32)1.0f)) || + ((new_fac < (FLOAT32)1.0f) && (*correction_fac > (FLOAT32)1.0f))) { + *correction_fac = (FLOAT32)1.0f; + } + + if ((*correction_fac < (FLOAT32)1.0f && new_fac < *correction_fac) || + (*correction_fac > (FLOAT32)1.0f && new_fac > *correction_fac)) + *correction_fac = (FLOAT32)0.85f * (*correction_fac) + (FLOAT32)0.15f * new_fac; + else + *correction_fac = (FLOAT32)0.7f * (*correction_fac) + (FLOAT32)0.3f * new_fac; + + *correction_fac = MIN(*correction_fac, (FLOAT32)1.15f); + *correction_fac = MAX(*correction_fac, (FLOAT32)0.85f); + } else { + *correction_fac = (FLOAT32)1.0f; + } + + return; +} + +static VOID iusace_calc_thr_exp(FLOAT32 **thr_exp, ia_psy_mod_out_data_struct *pstr_psy_out, + WORD32 num_chans, WORD32 chn) { + WORD32 sfb, ch, scf_band_grp, idx = 0; + ia_psy_mod_out_data_struct *pstr_psy_chan_out; + FLOAT32 *scf_band_thr; + FLOAT32 *ptr_thr_exp; + for (ch = chn; ch < chn + num_chans; ch++) { + pstr_psy_chan_out = &pstr_psy_out[ch]; + ptr_thr_exp = thr_exp[idx]; + for (scf_band_grp = 0; scf_band_grp < pstr_psy_chan_out->sfb_count; + scf_band_grp += pstr_psy_chan_out->sfb_per_group) { + FLOAT32 *thr_exp1 = &ptr_thr_exp[scf_band_grp]; + scf_band_thr = &pstr_psy_chan_out->ptr_sfb_thr[scf_band_grp]; + for (sfb = 0; sfb < pstr_psy_chan_out->max_sfb_per_grp; sfb++) { + thr_exp1[sfb] = (FLOAT32)pow(*scf_band_thr++, RED_EXP_VAL); + } + } + idx++; + } + + return; +} + +static VOID iusace_adapt_min_snr(ia_psy_mod_out_data_struct *pstr_psy_out, + ia_min_snr_adapt_param_struct *pstr_min_snr_params, + WORD32 num_chans, WORD32 chn) { + WORD32 num_sfb = 0, ch, scf_band_cnt, sfb_off, sfb; + FLOAT32 avg_energy = 0.0f, db_ratio, min_snr_red; + WORD32 i; + for (ch = chn; ch < chn + num_chans; ch++) { + ia_psy_mod_out_data_struct *pstr_psy_chan_out = &pstr_psy_out[ch]; + + num_sfb = 0; + avg_energy = 0; + scf_band_cnt = pstr_psy_chan_out->max_sfb_per_grp; + + for (sfb_off = 0; sfb_off < pstr_psy_chan_out->sfb_count; + sfb_off += pstr_psy_chan_out->sfb_per_group) { + FLOAT32 *sfb_energy = &pstr_psy_chan_out->ptr_sfb_energy[sfb_off]; + for (sfb = scf_band_cnt - 1; sfb >= 0; sfb--) { + avg_energy += sfb_energy[sfb]; + } + num_sfb += scf_band_cnt; + } + + if (num_sfb > 0) { + avg_energy /= num_sfb; + } + + for (sfb_off = 0; sfb_off < pstr_psy_chan_out->sfb_count; + sfb_off += pstr_psy_chan_out->sfb_per_group) { + i = sfb_off; + for (sfb = scf_band_cnt - 1; sfb >= 0; sfb--, i++) { + if (pstr_min_snr_params->start_ratio * pstr_psy_chan_out->ptr_sfb_energy[i] < + avg_energy) { + db_ratio = + (FLOAT32)(10.0 * log10((MIN_FLT_VAL + avg_energy) / + (MIN_FLT_VAL + pstr_psy_chan_out->ptr_sfb_energy[i]))); + min_snr_red = + pstr_min_snr_params->red_offs + pstr_min_snr_params->red_ratio_fac * db_ratio; + min_snr_red = MAX(min_snr_red, pstr_min_snr_params->max_red); + pstr_psy_chan_out->sfb_min_snr[i] = + (FLOAT32)pow(pstr_psy_out[ch].sfb_min_snr[i], min_snr_red); + pstr_psy_chan_out->sfb_min_snr[i] = MIN(MIN_SNR_LIMIT, pstr_psy_out[ch].sfb_min_snr[i]); + } + } + } + } + + return; +} + +static VOID iusace_init_avoid_hole_flag(WORD32 **ah_flag, + ia_psy_mod_out_data_struct *pstr_psy_out, + ia_ah_param_struct *pstr_ah_param, WORD32 num_chans, + WORD32 chn) { + WORD32 ch, idx; + FLOAT32 sfb_energy; + FLOAT32 scale_spread_energy; + WORD32 scf_band_grp, sfb, scf_band; + FLOAT32 *ptr_scf_band_spread_energy, *ptr_scf_band_energy, *ptr_scf_band_min_snr; + for (ch = chn; ch < chn + num_chans; ch++) { + ia_psy_mod_out_data_struct *pstr_psy_chan_out = &pstr_psy_out[ch]; + + if (pstr_psy_chan_out->window_sequence != EIGHT_SHORT_SEQUENCE) { + scale_spread_energy = 0.5f; + } else { + scale_spread_energy = 0.63f; + } + + for (scf_band_grp = 0; scf_band_grp < pstr_psy_chan_out->sfb_count; + scf_band_grp += pstr_psy_chan_out->sfb_per_group) { + ptr_scf_band_spread_energy = &pstr_psy_chan_out->ptr_sfb_spread_energy[scf_band_grp]; + sfb = pstr_psy_chan_out->max_sfb_per_grp; + for (scf_band = sfb - 1; scf_band >= 0; scf_band--) { + *ptr_scf_band_spread_energy = *ptr_scf_band_spread_energy * scale_spread_energy; + ptr_scf_band_spread_energy++; + } + } + } + + if (pstr_ah_param->modify_min_snr) { + for (ch = chn; ch < chn + num_chans; ch++) { + ia_psy_mod_out_data_struct *pstr_psy_chan_out = &pstr_psy_out[ch]; + ptr_scf_band_energy = pstr_psy_chan_out->ptr_sfb_energy; + + ptr_scf_band_min_snr = pstr_psy_chan_out->sfb_min_snr; + + for (scf_band_grp = 0; scf_band_grp < pstr_psy_chan_out->sfb_count; + scf_band_grp += pstr_psy_chan_out->sfb_per_group) { + for (scf_band = 0; scf_band < pstr_psy_chan_out->max_sfb_per_grp; scf_band++) { + FLOAT32 sfb_en_m1, sfb_en_p1, avg_energy; + if (scf_band > 0) { + sfb_en_m1 = ptr_scf_band_energy[scf_band_grp + scf_band - 1]; + } else { + sfb_en_m1 = ptr_scf_band_energy[scf_band_grp]; + } + if (scf_band < pstr_psy_chan_out->max_sfb_per_grp - 1) + sfb_en_p1 = ptr_scf_band_energy[scf_band_grp + scf_band + 1]; + else + sfb_en_p1 = ptr_scf_band_energy[scf_band_grp + scf_band]; + + avg_energy = (sfb_en_m1 + sfb_en_p1) / (FLOAT32)2.0f; + sfb_energy = ptr_scf_band_energy[scf_band_grp + scf_band]; + + if (sfb_energy > avg_energy) { + FLOAT32 temp_min_snr = MAX((FLOAT32)0.8f * avg_energy / sfb_energy, (FLOAT32)0.316f); + if (pstr_psy_chan_out->window_sequence != EIGHT_SHORT_SEQUENCE) + temp_min_snr = MAX(temp_min_snr, (FLOAT32)0.316f); + else + temp_min_snr = MAX(temp_min_snr, (FLOAT32)0.5f); + ptr_scf_band_min_snr[scf_band_grp + scf_band] = + MIN(ptr_scf_band_min_snr[scf_band_grp + scf_band], temp_min_snr); + } + + if (((FLOAT32)2.0f * sfb_energy < avg_energy) && (sfb_energy > (FLOAT32)0.0f)) { + FLOAT32 temp_min_snr = avg_energy / ((FLOAT32)2.0f * sfb_energy) * + ptr_scf_band_min_snr[scf_band_grp + scf_band]; + temp_min_snr = MIN((FLOAT32)0.8f, temp_min_snr); + ptr_scf_band_min_snr[scf_band_grp + scf_band] = + MIN(temp_min_snr, ptr_scf_band_min_snr[scf_band_grp + scf_band] * (FLOAT32)3.16f); + } + } + } + } + } + + if (num_chans == 2) { + ia_psy_mod_out_data_struct *psy_out_mid = &pstr_psy_out[chn]; + ia_psy_mod_out_data_struct *psy_out_side = &pstr_psy_out[chn + 1]; + + for (sfb = 0; sfb < psy_out_mid->sfb_count; sfb++) { + if (pstr_psy_out[chn].ms_used[sfb]) { + FLOAT32 sfb_en_mid = psy_out_mid->ptr_sfb_energy[sfb]; + FLOAT32 sfb_en_side = psy_out_side->ptr_sfb_energy[sfb]; + FLOAT32 max_sfb_en = MAX(sfb_en_mid, sfb_en_side); + FLOAT32 max_thr = 0.25f * psy_out_mid->sfb_min_snr[sfb] * max_sfb_en; + + psy_out_mid->sfb_min_snr[sfb] = (FLOAT32)MAX( + psy_out_mid->sfb_min_snr[sfb], + MIN(MAX_FLT_VAL, ((double)max_thr / (MIN_FLT_VAL + (double)sfb_en_mid)))); + + if (psy_out_mid->ptr_sfb_energy[sfb] <= 1.0f) { + psy_out_mid->ptr_sfb_energy[sfb] = MIN(psy_out_mid->ptr_sfb_energy[sfb], 0.8f); + } + + psy_out_side->sfb_min_snr[sfb] = (FLOAT32)MAX( + psy_out_side->sfb_min_snr[sfb], + MIN(MAX_FLT_VAL, ((double)max_thr / (MIN_FLT_VAL + (double)sfb_en_side)))); + + if (psy_out_side->sfb_min_snr[sfb] <= 1.0f) { + psy_out_side->sfb_min_snr[sfb] = MIN(psy_out_side->sfb_min_snr[sfb], 0.8f); + } + + if (sfb_en_mid > psy_out_mid->ptr_sfb_spread_energy[sfb]) { + psy_out_side->ptr_sfb_spread_energy[sfb] = 0.9f * sfb_en_side; + } + + if (sfb_en_side > psy_out_side->ptr_sfb_spread_energy[sfb]) { + psy_out_mid->ptr_sfb_spread_energy[sfb] = 0.9f * sfb_en_mid; + } + } + } + } + idx = 0; + for (ch = chn; ch < chn + num_chans; ch++) { + ia_psy_mod_out_data_struct *pstr_psy_chan_out = &pstr_psy_out[ch]; + for (scf_band_grp = 0; scf_band_grp < pstr_psy_chan_out->sfb_count; + scf_band_grp += pstr_psy_chan_out->sfb_per_group) { + for (scf_band = 0; scf_band < pstr_psy_chan_out->max_sfb_per_grp; scf_band++) { + if (pstr_psy_chan_out->ptr_sfb_spread_energy[scf_band_grp + scf_band] > + pstr_psy_chan_out->ptr_sfb_energy[scf_band_grp + scf_band] || + pstr_psy_chan_out->sfb_min_snr[scf_band_grp + scf_band] > (float)1.0) { + ah_flag[idx][scf_band_grp + scf_band] = NO_AH; + } else { + ah_flag[idx][scf_band_grp + scf_band] = AH_INACTIVE; + } + } + + for (scf_band = pstr_psy_chan_out->max_sfb_per_grp; + scf_band < pstr_psy_chan_out->sfb_per_group; scf_band++) { + ah_flag[idx][scf_band_grp + scf_band] = NO_AH; + } + } + idx++; + } + + return; +} + +static VOID iusace_reduce_thr(ia_psy_mod_out_data_struct *pstr_psy_out, WORD32 **ah_flag, + FLOAT32 **thr_exp, const FLOAT32 red_value, WORD32 num_channels, + WORD32 chn) { + WORD32 ch, sfb_group, sfb, idx = 0; + FLOAT32 sfb_energy, sfb_threshold, sfb_thr_reduced; + FLOAT32 *sfb_energy_fix, *sfb_threshold_fix, *sfb_min_snr_fix, *thr_exp_fix; + for (ch = chn; ch < chn + num_channels; ch++) { + ia_psy_mod_out_data_struct *pstr_psy_chan_out = &pstr_psy_out[ch]; + sfb_energy_fix = pstr_psy_chan_out->ptr_sfb_energy; + sfb_threshold_fix = pstr_psy_chan_out->ptr_sfb_thr; + sfb_min_snr_fix = pstr_psy_chan_out->sfb_min_snr; + thr_exp_fix = &thr_exp[idx][0]; + for (sfb_group = 0; sfb_group < pstr_psy_chan_out->sfb_count; + sfb_group += pstr_psy_chan_out->sfb_per_group) { + for (sfb = 0; sfb < pstr_psy_chan_out->max_sfb_per_grp; sfb++) { + sfb_energy = sfb_energy_fix[sfb_group + sfb]; + sfb_threshold = sfb_threshold_fix[sfb_group + sfb]; + if (sfb_energy > sfb_threshold) { + sfb_thr_reduced = + (FLOAT32)pow((thr_exp_fix[sfb_group + sfb] + red_value), INV_RED_EXP_VAL); + + if ((sfb_thr_reduced > sfb_min_snr_fix[sfb_group + sfb] * sfb_energy) && + (ah_flag[idx][sfb_group + sfb] != NO_AH)) { + sfb_thr_reduced = MAX(sfb_min_snr_fix[sfb_group + sfb] * sfb_energy, sfb_threshold); + ah_flag[idx][sfb_group + sfb] = AH_ACTIVE; + } + sfb_threshold_fix[sfb_group + sfb] = sfb_thr_reduced; + } + } + } + idx++; + } + + return; +} + +static VOID iusace_calc_pe_no_active_holes(FLOAT32 *pe, FLOAT32 *const_part, + FLOAT32 *nactive_lines, + ia_qc_pe_data_struct *pstr_qs_pe_data, + WORD32 **ah_flag, + ia_psy_mod_out_data_struct *pstr_psy_out, + WORD32 num_channels, WORD32 chn) { + WORD32 ch, sfb_group, sfb, idx = 0; + *pe = 0.0f; + *const_part = 0.0f; + *nactive_lines = 0; + for (ch = chn; ch < chn + num_channels; ch++) { + ia_psy_mod_out_data_struct *pstr_psy_chan_out = &pstr_psy_out[ch]; + ia_qc_pe_chan_data_struct *pe_channel_data = &pstr_qs_pe_data->pe_ch_data[idx]; + + for (sfb_group = 0; sfb_group < pstr_psy_chan_out->sfb_count; + sfb_group += pstr_psy_chan_out->sfb_per_group) { + for (sfb = 0; sfb < pstr_psy_chan_out->max_sfb_per_grp; sfb++) { + if (ah_flag[idx][sfb_group + sfb] < AH_ACTIVE) { + *pe += pe_channel_data->sfb_pe[sfb_group + sfb]; + *const_part += pe_channel_data->sfb_const_part[sfb_group + sfb]; + *nactive_lines += pe_channel_data->num_sfb_active_lines[sfb_group + sfb]; + } + } + } + idx++; + } + + return; +} + +static IA_ERRORCODE iusace_correct_thr(ia_psy_mod_out_data_struct *pstr_psy_out, WORD32 **ah_flag, + ia_qc_pe_data_struct *pstr_qs_pe_data, FLOAT32 **thr_exp, + const FLOAT32 red_value, const FLOAT32 delta_pe, + WORD32 num_channels, WORD32 chn, UWORD8 *ptr_scratch) { + WORD32 i, ch, sfb_group, sfb, idx = 0; + FLOAT32 delta_sfb_pe; + FLOAT32 thr_factor; + FLOAT32 norm_factor[2] = {0}; + FLOAT32 *sfb_pe_factors[2]; + for (i = 0; i < 2; i++) { + sfb_pe_factors[i] = (FLOAT32 *)ptr_scratch; + ptr_scratch += (MAX_NUM_GROUPED_SFB) * sizeof(sfb_pe_factors[0][0]); + } + FLOAT32 sfb_en, sfb_thr, sfb_thr_reduced; + FLOAT32 *p_thr_exp; + FLOAT32 *p_sfb_energy, *p_sfb_thr, *p_sfb_min_snr; + ia_psy_mod_out_data_struct *pstr_psy_chan_out = NULL; + ia_qc_pe_chan_data_struct *pe_channel_data = NULL; + + for (ch = chn; ch < chn + num_channels; ch++) { + if (idx >= IXHEAACE_MAX_CH_IN_BS_ELE) { + return IA_EXHEAACE_EXE_FATAL_USAC_INVALID_NUM_CHANNEL; + } + pstr_psy_chan_out = &pstr_psy_out[ch]; + pe_channel_data = &pstr_qs_pe_data->pe_ch_data[idx]; + norm_factor[idx] = MIN_FLT_VAL; + p_thr_exp = thr_exp[idx]; + + for (sfb_group = 0; sfb_group < pstr_psy_chan_out->sfb_count; + sfb_group += pstr_psy_chan_out->sfb_per_group) { + for (sfb = 0; sfb < pstr_psy_chan_out->max_sfb_per_grp; sfb++) { + if ((ah_flag[idx][sfb_group + sfb] < AH_ACTIVE) || (delta_pe > 0)) { + sfb_pe_factors[idx][sfb_group + sfb] = + pe_channel_data->num_sfb_active_lines[sfb_group + sfb] / + (p_thr_exp[sfb_group + sfb] + red_value); + norm_factor[idx] += sfb_pe_factors[idx][sfb_group + sfb]; + } else { + sfb_pe_factors[idx][sfb_group + sfb] = 0.0f; + } + } + } + idx++; + } + if (num_channels > 1) { + norm_factor[0] = norm_factor[0] + norm_factor[1]; + } + norm_factor[0] = 1.0f / norm_factor[0]; + idx = 0; + for (ch = chn; ch < chn + num_channels; ch++) { + if (idx >= IXHEAACE_MAX_CH_IN_BS_ELE) { + return IA_EXHEAACE_EXE_FATAL_USAC_INVALID_NUM_CHANNEL; + } + pstr_psy_chan_out = &pstr_psy_out[ch]; + pe_channel_data = &pstr_qs_pe_data->pe_ch_data[idx]; + p_sfb_energy = pstr_psy_chan_out->ptr_sfb_energy; + p_sfb_thr = pstr_psy_chan_out->ptr_sfb_thr; + p_sfb_min_snr = pstr_psy_chan_out->sfb_min_snr; + + for (sfb_group = 0; sfb_group < pstr_psy_chan_out->sfb_count; + sfb_group += pstr_psy_chan_out->sfb_per_group) { + i = sfb_group; + for (sfb = pstr_psy_chan_out->max_sfb_per_grp - 1; sfb >= 0; sfb--, i++) { + delta_sfb_pe = sfb_pe_factors[idx][i] * norm_factor[0] * delta_pe; + if (pe_channel_data->num_sfb_active_lines[i] > (FLOAT32)0.5f) { + sfb_en = p_sfb_energy[i]; + sfb_thr = p_sfb_thr[i]; + thr_factor = MIN(-delta_sfb_pe / pe_channel_data->num_sfb_active_lines[i], 20.f); + thr_factor = (FLOAT32)pow(2.0f, thr_factor); + sfb_thr_reduced = sfb_thr * thr_factor; + + if ((sfb_thr_reduced > p_sfb_min_snr[i] * sfb_en) && (ah_flag[idx][i] == AH_INACTIVE)) { + sfb_thr_reduced = MAX(p_sfb_min_snr[i] * sfb_en, sfb_thr); + ah_flag[idx][i] = AH_ACTIVE; + } + p_sfb_thr[i] = sfb_thr_reduced; + } + } + } + idx++; + } + + return IA_NO_ERROR; +} + +static VOID iusace_reduce_min_snr(ia_psy_mod_out_data_struct *pstr_psy_out, + ia_qc_pe_data_struct *pstr_qs_pe_data, WORD32 **ah_flag, + const FLOAT32 desired_pe, WORD32 num_channels, WORD32 chn) { + WORD32 sfb, sfb_sub_win, ch, idx; + FLOAT32 delta_pe; + + sfb_sub_win = pstr_psy_out[chn].max_sfb_per_grp; + + while (pstr_qs_pe_data->pe > desired_pe && sfb_sub_win > 0) { + sfb_sub_win--; + for (sfb = sfb_sub_win; sfb < pstr_psy_out[chn].sfb_count; + sfb += pstr_psy_out[chn].sfb_per_group) { + idx = 0; + for (ch = chn; ch < chn + num_channels; ch++) { + if (ah_flag[idx][sfb] != NO_AH && pstr_psy_out[ch].sfb_min_snr[sfb] < MIN_SNR_LIMIT) { + pstr_psy_out[ch].sfb_min_snr[sfb] = MIN_SNR_LIMIT; + pstr_psy_out[ch].ptr_sfb_thr[sfb] = + pstr_psy_out[ch].ptr_sfb_energy[sfb] * pstr_psy_out[ch].sfb_min_snr[sfb]; + delta_pe = pstr_qs_pe_data->pe_ch_data[idx].sfb_lines[sfb] * 1.5f - + pstr_qs_pe_data->pe_ch_data[idx].sfb_pe[sfb]; + pstr_qs_pe_data->pe += delta_pe; + pstr_qs_pe_data->pe_ch_data[idx].pe += delta_pe; + } + idx++; + } + if (pstr_qs_pe_data->pe <= desired_pe) break; + } + } + + return; +} + +static VOID iusace_allow_more_holes(ia_psy_mod_out_data_struct *pstr_psy_out, + ia_qc_pe_data_struct *pstr_qs_pe_data, WORD32 **ah_flag, + const ia_ah_param_struct *str_ah_param, + const FLOAT32 desired_pe, WORD32 num_channels, WORD32 chn, + UWORD8 *ptr_scratch) { + WORD32 sfb, ch, idx; + FLOAT32 act_pe = pstr_qs_pe_data->pe; + + if (num_channels == 2 && + pstr_psy_out[chn].window_sequence == pstr_psy_out[chn + 1].window_sequence) { + ia_psy_mod_out_data_struct *psy_out_left = &pstr_psy_out[chn]; + ia_psy_mod_out_data_struct *psy_out_right = &pstr_psy_out[chn + 1]; + + for (sfb = 0; sfb < psy_out_left->sfb_count; sfb++) { + if (pstr_psy_out[chn].ms_used[sfb]) { + if (ah_flag[1][sfb] != NO_AH && + 0.4f * psy_out_left->sfb_min_snr[sfb] * psy_out_left->ptr_sfb_energy[sfb] > + psy_out_right->ptr_sfb_energy[sfb]) { + ah_flag[1][sfb] = NO_AH; + + psy_out_right->ptr_sfb_thr[sfb] = 2.0f * psy_out_right->ptr_sfb_energy[sfb]; + + act_pe -= pstr_qs_pe_data->pe_ch_data[1].sfb_pe[sfb]; + } else { + if (ah_flag[0][sfb] != NO_AH && + 0.4f * psy_out_right->sfb_min_snr[sfb] * psy_out_right->ptr_sfb_energy[sfb] > + psy_out_left->ptr_sfb_energy[sfb]) { + ah_flag[0][sfb] = NO_AH; + + psy_out_left->ptr_sfb_thr[sfb] = 2.0f * psy_out_left->ptr_sfb_energy[sfb]; + + act_pe -= pstr_qs_pe_data->pe_ch_data[0].sfb_pe[sfb]; + } + } + if (act_pe < desired_pe) break; + } + } + } + if (act_pe > desired_pe) { + WORD32 *start_sfb = (WORD32 *)ptr_scratch; + memset(start_sfb, 0, MAX_TIME_CHANNELS * sizeof(start_sfb[0])); + FLOAT32 average_energy, min_energy; + WORD32 ah_cnt; + WORD32 en_idx; + FLOAT32 energy[4]; + WORD32 min_sfb, max_sfb; + WORD32 done; + for (ch = chn; ch < chn + num_channels; ch++) { + if (pstr_psy_out[ch].window_sequence != EIGHT_SHORT_SEQUENCE) + start_sfb[ch] = str_ah_param->start_sfb_long; + else + start_sfb[ch] = str_ah_param->start_sfb_short; + } + + average_energy = 0.0f; + min_energy = MAX_FLT_VAL; + ah_cnt = 0; + idx = 0; + for (ch = chn; ch < chn + num_channels; ch++) { + ia_psy_mod_out_data_struct *pstr_psy_chan_out = &pstr_psy_out[ch]; + for (sfb = start_sfb[ch]; sfb < pstr_psy_chan_out->sfb_count; sfb++) { + if ((ah_flag[idx][sfb] != NO_AH) && + (pstr_psy_chan_out->ptr_sfb_energy[sfb] > pstr_psy_chan_out->ptr_sfb_thr[sfb])) { + min_energy = MIN(min_energy, pstr_psy_chan_out->ptr_sfb_energy[sfb]); + average_energy += pstr_psy_chan_out->ptr_sfb_energy[sfb]; + ah_cnt++; + } + } + idx++; + } + + average_energy = MIN(MAX_FLT_VAL, average_energy / (ah_cnt + MIN_FLT_VAL)); + + for (en_idx = 0; en_idx < 4; en_idx++) { + energy[en_idx] = min_energy * (FLOAT32)pow(average_energy / (min_energy + MIN_FLT_VAL), + (2 * en_idx + 1) / 7.0f); + } + max_sfb = pstr_psy_out[chn].sfb_count - 1; + min_sfb = start_sfb[chn]; + + if (num_channels == 2) { + max_sfb = MAX(max_sfb, pstr_psy_out[chn + 1].sfb_count - 1); + + min_sfb = MIN(min_sfb, start_sfb[chn + 1]); + } + + sfb = max_sfb; + en_idx = 0; + done = 0; + while (!done) { + idx = 0; + for (ch = chn; ch < chn + num_channels; ch++) { + ia_psy_mod_out_data_struct *pstr_psy_chan_out = &pstr_psy_out[ch]; + if (sfb >= start_sfb[ch] && sfb < pstr_psy_chan_out->sfb_count) { + if (ah_flag[idx][sfb] != NO_AH && + pstr_psy_chan_out->ptr_sfb_energy[sfb] < energy[en_idx]) { + ah_flag[idx][sfb] = NO_AH; + pstr_psy_chan_out->ptr_sfb_thr[sfb] = 2.0f * pstr_psy_chan_out->ptr_sfb_energy[sfb]; + act_pe -= pstr_qs_pe_data->pe_ch_data[idx].sfb_pe[sfb]; + } + + if (act_pe < desired_pe) { + done = 1; + break; + } + } + idx++; + } + sfb--; + if (sfb < min_sfb) { + sfb = max_sfb; + en_idx++; + if (en_idx >= 4) { + done = 1; + } + } + } + } + + return; +} + +static IA_ERRORCODE iusace_adapt_thr_to_pe(ia_psy_mod_out_data_struct *pstr_psy_out, + ia_qc_pe_data_struct *pstr_qs_pe_data, + const FLOAT32 desired_pe, + ia_ah_param_struct *str_ah_param, + ia_min_snr_adapt_param_struct *msa_param, + WORD32 num_channels, WORD32 chn, UWORD8 *ptr_scratch) { + IA_ERRORCODE err_code; + FLOAT32 no_red_pe, red_pe, red_pe_no_ah; + FLOAT32 const_part, const_part_no_ah; + FLOAT32 nactive_lines, nactive_lines_no_ah; + FLOAT32 desired_pe_no_ah; + FLOAT32 avg_thr_exp, redval; + WORD32 *ah_flag[2]; + WORD32 iteration; + for (WORD32 i = 0; i < 2; i++) { + ah_flag[i] = (WORD32 *)ptr_scratch; + ptr_scratch += (MAX_NUM_GROUPED_SFB) * sizeof(ah_flag[0][0]); + } + FLOAT32 *thr_exp[2]; + for (WORD32 i = 0; i < 2; i++) { + thr_exp[i] = (FLOAT32 *)ptr_scratch; + ptr_scratch += (MAX_NUM_GROUPED_SFB) * sizeof(thr_exp[0][0]); + } + + iusace_calc_thr_exp(thr_exp, pstr_psy_out, num_channels, chn); + iusace_adapt_min_snr(pstr_psy_out, msa_param, num_channels, chn); + iusace_init_avoid_hole_flag(ah_flag, pstr_psy_out, str_ah_param, num_channels, chn); + + no_red_pe = pstr_qs_pe_data->pe; + const_part = pstr_qs_pe_data->const_part; + nactive_lines = pstr_qs_pe_data->num_active_lines; + avg_thr_exp = (FLOAT32)pow(2.0f, (const_part - no_red_pe) / (INV_RED_EXP_VAL * nactive_lines)); + redval = (FLOAT32)pow(2.0f, (const_part - desired_pe) / (INV_RED_EXP_VAL * nactive_lines)) - + avg_thr_exp; + redval = MAX(0.0f, redval); + + iusace_reduce_thr(pstr_psy_out, ah_flag, thr_exp, redval, num_channels, chn); + + iusace_calc_sfb_pe_data(pstr_qs_pe_data, pstr_psy_out, num_channels, chn); + red_pe = pstr_qs_pe_data->pe; + + iteration = 0; + do { + iusace_calc_pe_no_active_holes(&red_pe_no_ah, &const_part_no_ah, &nactive_lines_no_ah, + pstr_qs_pe_data, ah_flag, pstr_psy_out, num_channels, chn); + + desired_pe_no_ah = MAX(desired_pe - (red_pe - red_pe_no_ah), 0); + if (nactive_lines_no_ah > 0) { + avg_thr_exp = (FLOAT32)pow( + 2.0f, (const_part_no_ah - red_pe_no_ah) / (INV_RED_EXP_VAL * nactive_lines_no_ah)); + redval += (FLOAT32)pow(2.0f, (const_part_no_ah - desired_pe_no_ah) / + (INV_RED_EXP_VAL * nactive_lines_no_ah)) - + avg_thr_exp; + redval = MAX(0.0f, redval); + iusace_reduce_thr(pstr_psy_out, ah_flag, thr_exp, redval, num_channels, chn); + } + + iusace_calc_sfb_pe_data(pstr_qs_pe_data, pstr_psy_out, num_channels, chn); + red_pe = pstr_qs_pe_data->pe; + iteration++; + } while ((fabs(red_pe - desired_pe) > (0.05f) * desired_pe) && (iteration < 2)); + if (red_pe < 1.15f * desired_pe) { + err_code = iusace_correct_thr(pstr_psy_out, ah_flag, pstr_qs_pe_data, thr_exp, redval, + desired_pe - red_pe, num_channels, chn, ptr_scratch); + if (err_code != IA_NO_ERROR) { + return err_code; + } + } else { + iusace_reduce_min_snr(pstr_psy_out, pstr_qs_pe_data, ah_flag, 1.05f * desired_pe, + num_channels, chn); + iusace_allow_more_holes(pstr_psy_out, pstr_qs_pe_data, ah_flag, str_ah_param, + 1.05f * desired_pe, num_channels, chn, ptr_scratch); + } + + return IA_NO_ERROR; +} + +IA_ERRORCODE iusace_adj_thr(ia_adj_thr_elem_struct *pstr_adj_thr_elem, + ia_psy_mod_out_data_struct *pstr_psy_out, FLOAT32 *ch_bit_dist, + ia_qc_out_data_struct *pstr_qc_out, const WORD32 avg_bits, + const WORD32 bitres_bits, const WORD32 max_bitres_bits, + const WORD32 side_info_bits, FLOAT32 *max_bit_fac, + WORD32 num_channels, WORD32 chn, iusace_scratch_mem *pstr_scratch) { + IA_ERRORCODE err_code; + FLOAT32 no_red_pe, granted_pe, granted_pe_corr; + WORD32 curr_win_sequence; + ia_qc_pe_data_struct *pstr_qc_pe_data = (ia_qc_pe_data_struct *)pstr_scratch->ptr_fd_scratch; + pUWORD8 ptr_scratch = pstr_scratch->ptr_fd_scratch + sizeof(ia_qc_pe_data_struct); + FLOAT32 bit_factor; + WORD32 ch; + + pstr_qc_pe_data->pe_ch_data[0].sfb_lines = pstr_scratch->ptr_sfb_num_relevant_lines[0]; + pstr_qc_pe_data->pe_ch_data[0].sfb_ld_energy = pstr_scratch->ptr_sfb_ld_energy[0]; + if (num_channels == 2) { + pstr_qc_pe_data->pe_ch_data[1].sfb_lines = pstr_scratch->ptr_sfb_num_relevant_lines[1]; + pstr_qc_pe_data->pe_ch_data[1].sfb_ld_energy = pstr_scratch->ptr_sfb_ld_energy[1]; + } + pstr_qc_pe_data->offset = pstr_adj_thr_elem->pe_offset; + + iusace_calc_sfb_pe_data(pstr_qc_pe_data, pstr_psy_out, num_channels, chn); + no_red_pe = pstr_qc_pe_data->pe; + + curr_win_sequence = ONLY_LONG_SEQUENCE; + if (num_channels == 2) { + if ((pstr_psy_out[chn].window_sequence == EIGHT_SHORT_SEQUENCE) || + (pstr_psy_out[chn + 1].window_sequence == EIGHT_SHORT_SEQUENCE)) { + curr_win_sequence = EIGHT_SHORT_SEQUENCE; + } + } else { + curr_win_sequence = pstr_psy_out[chn].window_sequence; + } + + bit_factor = + iusace_bitres_calc_bitfac(bitres_bits, max_bitres_bits, no_red_pe + 5.0f * side_info_bits, + curr_win_sequence, avg_bits, *max_bit_fac, pstr_adj_thr_elem); + granted_pe = bit_factor * iusace_bits_to_pe((FLOAT32)avg_bits); + iusace_calc_pe_correction(&(pstr_adj_thr_elem->pe_correction_fac), MIN(granted_pe, no_red_pe), + pstr_adj_thr_elem->pe_last, pstr_adj_thr_elem->dyn_bits_last); + granted_pe_corr = granted_pe * pstr_adj_thr_elem->pe_correction_fac; + + if (granted_pe_corr < no_red_pe) { + err_code = iusace_adapt_thr_to_pe( + pstr_psy_out, pstr_qc_pe_data, granted_pe_corr, &pstr_adj_thr_elem->str_ah_param, + &pstr_adj_thr_elem->str_min_snr_adapt_params, num_channels, chn, ptr_scratch); + if (err_code != IA_NO_ERROR) { + return err_code; + } + } + + for (ch = 0; ch < num_channels; ch++) { + FLOAT32 tmp_var, temp1; + if (pstr_qc_pe_data->pe) { + tmp_var = 1.0f - num_channels * 0.2f; + temp1 = pstr_qc_pe_data->pe_ch_data[ch].pe / pstr_qc_pe_data->pe; + temp1 = temp1 * tmp_var; + ch_bit_dist[ch] = temp1 + 0.2f; + if (ch_bit_dist[ch] < 0.2f) ch_bit_dist[ch] = 0.2f; + } else { + ch_bit_dist[ch] = 0.2f; + } + } + + pstr_qc_out->pe = no_red_pe; + pstr_adj_thr_elem->pe_last = granted_pe; + + return IA_NO_ERROR; +} + +VOID iusace_calc_form_fac_per_chan(ia_psy_mod_out_data_struct *pstr_psy_out_chan, + iusace_scratch_mem *pstr_scratch, WORD32 i_ch) { + WORD32 i, j, sfb_offs; + WORD32 sfb, sfb_width; + FLOAT32 *ptr_sfb_form_factor = pstr_scratch->ptr_sfb_form_fac[i_ch]; + FLOAT32 *ptr_sfb_num_relevant_lines = pstr_scratch->ptr_sfb_num_relevant_lines[i_ch]; + FLOAT32 *ptr_sfb_ld_energy = pstr_scratch->ptr_sfb_ld_energy[i_ch]; + + memset(ptr_sfb_num_relevant_lines, 0, sizeof(FLOAT32) * pstr_psy_out_chan->sfb_count); + + for (sfb_offs = 0; sfb_offs < pstr_psy_out_chan->sfb_count; + sfb_offs += pstr_psy_out_chan->sfb_per_group) { + i = sfb_offs; + for (sfb = 0; sfb < pstr_psy_out_chan->max_sfb_per_grp; sfb++, i++) { + ptr_sfb_form_factor[i] = MIN_FLT_VAL; + if (pstr_psy_out_chan->ptr_sfb_energy[i] > pstr_psy_out_chan->ptr_sfb_thr[i]) { + FLOAT32 avg_form_factor; + + for (j = pstr_psy_out_chan->sfb_offsets[i]; j < pstr_psy_out_chan->sfb_offsets[i + 1]; + j++) { + ptr_sfb_form_factor[i] += (FLOAT32)sqrt(fabs(pstr_psy_out_chan->ptr_spec_coeffs[j])); + } + + sfb_width = pstr_psy_out_chan->sfb_offsets[i + 1] - pstr_psy_out_chan->sfb_offsets[i]; + avg_form_factor = + (FLOAT32)pow(pstr_psy_out_chan->ptr_sfb_energy[i] / (FLOAT32)sfb_width, 0.25); + ptr_sfb_num_relevant_lines[i] = ptr_sfb_form_factor[i] / avg_form_factor; + ptr_sfb_ld_energy[i] = (FLOAT32)(log(pstr_psy_out_chan->ptr_sfb_energy[i]) * LOG2_1); + } + } + } + + return; +} + +VOID iusace_quantize_lines(const WORD32 gain, const WORD32 num_lines, FLOAT32 *ptr_exp_spectrum, + WORD16 *ptr_quant_spectrum, FLOAT32 *ptr_mdct_spec) { + FLOAT32 quantizer; + FLOAT32 k = 0.4054f; + WORD32 line; + + quantizer = ixheaace_fd_quant_table[gain + 128]; + for (line = 0; line < num_lines; line++) { + FLOAT32 tmp = ptr_mdct_spec[line]; + if (tmp < 0.0f) { + ptr_exp_spectrum[line] = (FLOAT32)sqrt(-tmp); + ptr_exp_spectrum[line] *= (FLOAT32)sqrt(ptr_exp_spectrum[line]); + ptr_quant_spectrum[line] = -(WORD16)(k + quantizer * ptr_exp_spectrum[line]); + } else { + ptr_exp_spectrum[line] = (FLOAT32)sqrt(tmp); + ptr_exp_spectrum[line] *= (FLOAT32)sqrt(ptr_exp_spectrum[line]); + ptr_quant_spectrum[line] = (WORD16)(k + quantizer * ptr_exp_spectrum[line]); + } + } + return; +} + +VOID iusace_calculate_exp_spec(const WORD32 num_lines, FLOAT32 *ptr_exp_spectrum, + FLOAT32 *ptr_mdct_spec) { + WORD32 line; + + for (line = 0; line < num_lines; line++) { + ptr_exp_spectrum[line] = (FLOAT32)sqrt(fabs(ptr_mdct_spec[line])); + ptr_exp_spectrum[line] *= (FLOAT32)sqrt(ptr_exp_spectrum[line]); + } + return; +} + +static WORD32 iusace_scf_delta_bit_count(WORD32 delta) { + if (delta > 60) { + return (iusace_huffman_code_table[120][0]); + } + if (delta < -60) { + return (iusace_huffman_code_table[0][0]); + } + return (iusace_huffman_code_table[delta + 60][0]); +} + +static WORD32 iusace_count_single_scf_bits(WORD32 scf, WORD32 left_scf, WORD32 right_scf) { + WORD32 scf_bits; + + scf_bits = + iusace_scf_delta_bit_count(left_scf - scf) + iusace_scf_delta_bit_count(scf - right_scf); + + return scf_bits; +} + +static FLOAT32 iusace_calc_single_spec_pe(WORD32 scf, FLOAT32 sfb_const_pe_part, + FLOAT32 num_lines) { + FLOAT32 spec_pe; + FLOAT32 ld_ratio; + + ld_ratio = sfb_const_pe_part - (FLOAT32)0.375f * (FLOAT32)scf; + + if (ld_ratio >= PE_C1) { + spec_pe = (FLOAT32)0.7f * num_lines * ld_ratio; + } else { + spec_pe = (FLOAT32)0.7f * num_lines * (PE_C2 + PE_C3 * ld_ratio); + } + + return spec_pe; +} + +static WORD32 iusace_count_scf_bits_diff(WORD16 *ptr_sfb_prev, WORD16 *ptr_sfb_new, + WORD32 sfb_count, WORD32 start_sfb, WORD32 stop_sfb) { + WORD32 scf_bits_diff = 0; + WORD32 sfb = 0, sfb_last; + WORD32 sfb_prev, sfb_next; + + sfb_last = start_sfb; + + while ((sfb_last < stop_sfb) && (ptr_sfb_prev[sfb_last] == SHRT_MIN)) { + sfb_last++; + } + + sfb_prev = start_sfb - 1; + + while ((sfb_prev >= 0) && (ptr_sfb_prev[sfb_prev] == SHRT_MIN)) { + sfb_prev--; + } + + if (sfb_prev >= 0) { + scf_bits_diff += iusace_scf_delta_bit_count(ptr_sfb_new[sfb_prev] - ptr_sfb_new[sfb_last]) - + iusace_scf_delta_bit_count(ptr_sfb_prev[sfb_prev] - ptr_sfb_prev[sfb_last]); + } + + for (sfb = sfb_last + 1; sfb < stop_sfb; sfb++) { + if (ptr_sfb_prev[sfb] != SHRT_MIN) { + scf_bits_diff += iusace_scf_delta_bit_count(ptr_sfb_new[sfb_last] - ptr_sfb_new[sfb]) - + iusace_scf_delta_bit_count(ptr_sfb_prev[sfb_last] - ptr_sfb_prev[sfb]); + + sfb_last = sfb; + } + } + + sfb_next = stop_sfb; + + while ((sfb_next < sfb_count) && (ptr_sfb_prev[sfb_next] == SHRT_MIN)) { + sfb_next++; + } + + if (sfb_next < sfb_count) { + scf_bits_diff += iusace_scf_delta_bit_count(ptr_sfb_new[sfb_last] - ptr_sfb_new[sfb_next]) - + iusace_scf_delta_bit_count(ptr_sfb_prev[sfb_last] - ptr_sfb_prev[sfb_next]); + } + + return scf_bits_diff; +} + +static FLOAT32 iusace_calc_spec_pe_diff(ia_psy_mod_out_data_struct *pstr_psy_out, + WORD16 *scf_prev, WORD16 *scf_new, + FLOAT32 *ptr_sfb_const_pe_part, FLOAT32 *ptr_sfb_form_fac, + FLOAT32 *ptr_sfb_num_rel_lines, WORD32 start_sfb, + WORD32 stop_sfb) { + FLOAT32 spec_pe_diff = 0.0f; + WORD32 sfb; + + for (sfb = start_sfb; sfb < stop_sfb; sfb++) { + if (scf_prev[sfb] != SHRT_MIN) { + FLOAT32 ld_ratio_prev, ld_ratio_new, pe_prev, pe_new; + + if (ptr_sfb_const_pe_part[sfb] == MIN_FLT_VAL) { + ptr_sfb_const_pe_part[sfb] = (FLOAT32)log(pstr_psy_out->ptr_sfb_energy[sfb] * + (FLOAT32)6.75f / ptr_sfb_form_fac[sfb]) * + LOG2_1; + } + + ld_ratio_prev = ptr_sfb_const_pe_part[sfb] - 0.375f * scf_prev[sfb]; + ld_ratio_new = ptr_sfb_const_pe_part[sfb] - 0.375f * scf_new[sfb]; + + if (ld_ratio_prev >= PE_C1) { + pe_prev = ld_ratio_prev; + } else { + pe_prev = PE_C2 + PE_C3 * ld_ratio_prev; + } + + if (ld_ratio_new >= PE_C1) { + pe_new = ld_ratio_new; + } else { + pe_new = PE_C2 + PE_C3 * ld_ratio_new; + } + + spec_pe_diff += (FLOAT32)0.7f * ptr_sfb_num_rel_lines[sfb] * (pe_new - pe_prev); + } + } + + return spec_pe_diff; +} + +FLOAT32 iusace_calc_sfb_dist(const FLOAT32 *ptr_spec, const FLOAT32 *ptr_exp_spec, + WORD16 *ptr_quant_spec, WORD32 sfb_width, WORD32 gain) { + WORD32 i; + FLOAT32 dist = 0; + FLOAT32 k = 0.4054f; + FLOAT32 quantizer = ixheaace_fd_quant_table[gain + 128]; + FLOAT32 inv_quantizer = ixheaace_fd_inv_quant_table[gain + 128]; + + for (i = 0; i < sfb_width; i++) { + FLOAT32 iq_val; + FLOAT32 diff; + + ptr_quant_spec[i] = (WORD16)(k + quantizer * ptr_exp_spec[i]); + + if (ptr_quant_spec[i] < 64) { + iq_val = ixheaace_pow_4_3_table[ptr_quant_spec[i]] * inv_quantizer; + } else { + iq_val = (FLOAT32)((pow((FLOAT32)abs(ptr_quant_spec[i]), 4.0f / 3.0f)) * inv_quantizer); + } + + diff = (FLOAT32)fabs(ptr_spec[i]) - iq_val; + + dist += diff * diff; + } + + return dist; +} + +static WORD16 iusace_improve_scf(FLOAT32 *ptr_spec, FLOAT32 *ptr_exp_spec, WORD16 *ptr_quant_spec, + WORD16 *ptr_quant_spec_temp, WORD32 sfb_width, FLOAT32 threshold, + WORD16 scf, WORD16 min_scf, FLOAT32 *dist, + WORD16 *ptr_min_calc_scf) { + FLOAT32 sfb_dist; + WORD16 best_scf = scf; + WORD32 j; + + sfb_dist = iusace_calc_sfb_dist(ptr_spec, ptr_exp_spec, ptr_quant_spec, sfb_width, scf); + + *ptr_min_calc_scf = scf; + + if (sfb_dist > (1.25 * threshold)) { + WORD16 estimated_scf = scf; + FLOAT32 best_sfb_dist = sfb_dist; + WORD32 count; + + count = 0; + + while ((sfb_dist > (1.25 * threshold)) && (count++ < 3)) { + scf++; + + sfb_dist = + iusace_calc_sfb_dist(ptr_spec, ptr_exp_spec, ptr_quant_spec_temp, sfb_width, scf); + + if (sfb_dist < best_sfb_dist) { + best_scf = scf; + best_sfb_dist = sfb_dist; + + memcpy(ptr_quant_spec, ptr_quant_spec_temp, sfb_width * sizeof(WORD16)); + } + } + + count = 0; + scf = estimated_scf; + sfb_dist = best_sfb_dist; + + while ((sfb_dist > (1.25 * threshold)) && (count++ < 1) && (scf > min_scf)) { + scf--; + + sfb_dist = + iusace_calc_sfb_dist(ptr_spec, ptr_exp_spec, ptr_quant_spec_temp, sfb_width, scf); + + if (sfb_dist < best_sfb_dist) { + best_scf = scf; + best_sfb_dist = sfb_dist; + + memcpy(ptr_quant_spec, ptr_quant_spec_temp, sfb_width * sizeof(WORD16)); + } + *ptr_min_calc_scf = scf; + } + *dist = best_sfb_dist; + } else { + FLOAT32 best_sfb_dist = sfb_dist; + FLOAT32 allowed_sfb_dist = MIN(sfb_dist * 1.25f, threshold); + WORD32 count; + + for (count = 0; count < 3; count++) { + scf++; + + sfb_dist = + iusace_calc_sfb_dist(ptr_spec, ptr_exp_spec, ptr_quant_spec_temp, sfb_width, scf); + + if (sfb_dist < allowed_sfb_dist) { + *ptr_min_calc_scf = best_scf + 1; + + best_scf = scf; + best_sfb_dist = sfb_dist; + memcpy(ptr_quant_spec, ptr_quant_spec_temp, sfb_width * sizeof(WORD16)); + } + } + *dist = best_sfb_dist; + } + + for (j = 0; j < sfb_width; j++) { + if (ptr_spec[j] < 0) { + ptr_quant_spec[j] = -ptr_quant_spec[j]; + } + } + + return best_scf; +} + +static VOID iusace_assimilate_single_scf(ia_psy_mod_out_data_struct *pstr_psy_out, + FLOAT32 *ptr_exp_spec, WORD16 *ptr_quant_spec, + WORD16 *ptr_quant_spec_temp, WORD16 *scf, + WORD16 *ptr_min_scf, FLOAT32 *ptr_sfb_dist, + FLOAT32 *ptr_sfb_const_pe_part, + FLOAT32 *ptr_sfb_form_fac, FLOAT32 *ptr_sfb_num_lines, + WORD16 *ptr_min_calc_scf, FLOAT32 *ptr_mdct_spec_float) { + WORD32 sfb_prev, sfb_act, sfb_next; + WORD16 scf_act = 0, *scf_prev, *scf_next, min_scf, max_scf; + WORD32 sfb_width, sfb_offs; + FLOAT32 energy; + FLOAT32 sfb_pe_prev, sfb_pe_new; + FLOAT32 sfb_dist_new; + WORD32 j; + WORD32 success = 0; + FLOAT32 delta_pe = 0.0f, delta_pe_new, delta_pe_temp; + WORD16 prev_scf_last[MAX_NUM_GROUPED_SFB], prev_scf_next[MAX_NUM_GROUPED_SFB]; + FLOAT32 delta_pe_last[MAX_NUM_GROUPED_SFB]; + WORD32 update_min_scf; + + for (j = 0; j < pstr_psy_out->sfb_count; j++) { + prev_scf_last[j] = SHRT_MAX; + prev_scf_next[j] = SHRT_MAX; + delta_pe_last[j] = MAX_FLT_VAL; + } + + sfb_prev = -1; + sfb_act = -1; + sfb_next = -1; + scf_prev = 0; + scf_next = 0; + min_scf = SHRT_MAX; + max_scf = SHRT_MAX; + + do { + sfb_next++; + + while ((sfb_next < pstr_psy_out->sfb_count) && (scf[sfb_next] == SHRT_MIN)) { + sfb_next++; + } + + if ((sfb_prev >= 0) && (sfb_act >= 0) && (sfb_next < pstr_psy_out->sfb_count)) { + scf_act = scf[sfb_act]; + + scf_prev = scf + sfb_prev; + scf_next = scf + sfb_next; + + min_scf = MIN(*scf_prev, *scf_next); + + max_scf = MAX(*scf_prev, *scf_next); + } else { + if ((sfb_prev == -1) && (sfb_act >= 0) && (sfb_next < pstr_psy_out->sfb_count)) { + scf_act = scf[sfb_act]; + + scf_prev = &scf_act; + + scf_next = scf + sfb_next; + + min_scf = *scf_next; + + max_scf = *scf_next; + } else { + if ((sfb_prev >= 0) && (sfb_act >= 0) && (sfb_next == pstr_psy_out->sfb_count)) { + scf_act = scf[sfb_act]; + + scf_prev = scf + sfb_prev; + + scf_next = &scf_act; + + min_scf = *scf_prev; + + max_scf = *scf_prev; + } + } + } + + if (sfb_act >= 0) { + min_scf = MAX(min_scf, ptr_min_scf[sfb_act]); + } + + if ((sfb_act >= 0) && (sfb_prev >= 0 || sfb_next < pstr_psy_out->sfb_count) && + (scf_act > min_scf) && (scf_act <= min_scf + MAX_SCF_DELTA) && + (scf_act >= max_scf - MAX_SCF_DELTA) && + (*scf_prev != prev_scf_last[sfb_act] || *scf_next != prev_scf_next[sfb_act] || + delta_pe < delta_pe_last[sfb_act])) { + success = 0; + + sfb_width = pstr_psy_out->sfb_offsets[sfb_act + 1] - pstr_psy_out->sfb_offsets[sfb_act]; + + sfb_offs = pstr_psy_out->sfb_offsets[sfb_act]; + + energy = pstr_psy_out->ptr_sfb_energy[sfb_act]; + + if (ptr_sfb_const_pe_part[sfb_act] == MIN_FLT_VAL) { + ptr_sfb_const_pe_part[sfb_act] = + (FLOAT32)log(energy * (FLOAT32)6.75f / ptr_sfb_form_fac[sfb_act]) * LOG2_1; + } + + sfb_pe_prev = iusace_calc_single_spec_pe(scf_act, ptr_sfb_const_pe_part[sfb_act], + ptr_sfb_num_lines[sfb_act]) + + iusace_count_single_scf_bits(scf_act, *scf_prev, *scf_next); + + delta_pe_new = delta_pe; + update_min_scf = 1; + + do { + scf_act--; + + if (scf_act < ptr_min_calc_scf[sfb_act] && scf_act >= max_scf - MAX_SCF_DELTA) { + sfb_pe_new = iusace_calc_single_spec_pe(scf_act, ptr_sfb_const_pe_part[sfb_act], + ptr_sfb_num_lines[sfb_act]) + + (FLOAT32)iusace_count_single_scf_bits(scf_act, *scf_prev, *scf_next); + + delta_pe_temp = delta_pe + sfb_pe_new - sfb_pe_prev; + + if (delta_pe_temp < (FLOAT32)10.0f) { + sfb_dist_new = + iusace_calc_sfb_dist(ptr_mdct_spec_float + sfb_offs, ptr_exp_spec + sfb_offs, + ptr_quant_spec_temp + sfb_offs, sfb_width, scf_act); + + if (sfb_dist_new < ptr_sfb_dist[sfb_act]) { + scf[sfb_act] = scf_act; + ptr_sfb_dist[sfb_act] = sfb_dist_new; + + for (j = sfb_offs; j < sfb_offs + sfb_width; j++) { + ptr_quant_spec[j] = ptr_quant_spec_temp[j]; + + if (ptr_mdct_spec_float[j] < 0.0f) { + ptr_quant_spec[j] = -ptr_quant_spec[j]; + } + } + delta_pe_new = delta_pe_temp; + success = 1; + } + + if (update_min_scf) { + ptr_min_calc_scf[sfb_act] = scf_act; + } + } else { + update_min_scf = 0; + } + } + } while (scf_act > min_scf); + + delta_pe = delta_pe_new; + + prev_scf_last[sfb_act] = *scf_prev; + prev_scf_next[sfb_act] = *scf_next; + delta_pe_last[sfb_act] = delta_pe; + } + + if (success) { + sfb_prev = -1; + sfb_act = -1; + sfb_next = -1; + scf_prev = 0; + scf_next = 0; + min_scf = SHRT_MAX; + max_scf = SHRT_MAX; + success = 0; + } else { + sfb_prev = sfb_act; + sfb_act = sfb_next; + } + } while (sfb_next < pstr_psy_out->sfb_count); + return; +} + +static VOID iusace_assimilate_multiple_scf(ia_psy_mod_out_data_struct *pstr_psy_out, + FLOAT32 *ptr_exp_spec, WORD16 *ptr_quant_spec, + WORD16 *ptr_quant_spec_temp, WORD16 *ptr_scf, + WORD16 *ptr_min_scf, FLOAT32 *ptr_sfb_dist, + FLOAT32 *ptr_sfb_const_pe_part, + FLOAT32 *ptr_sfb_form_fac, FLOAT32 *ptr_sfb_num_lines, + FLOAT32 *ptr_mdct_spec_float, pUWORD8 pstr_scratch) { + WORD32 sfb, start_sfb, stop_sfb; + WORD16 scf_temp[MAX_NUM_GROUPED_SFB], min_scf, max_scf, scf_act; + WORD32 possible_region_found; + WORD32 sfb_width, sfb_offs, j; + FLOAT32 prev_dist_sum, new_dist_sum; + WORD32 delta_scf_bits; + FLOAT32 delta_spec_pe; + FLOAT32 delta_pe = 0.0f, delta_pe_new; + WORD32 sfb_count = pstr_psy_out->sfb_count; + FLOAT32 *sfb_dist_new = (FLOAT32 *)pstr_scratch; + min_scf = SHRT_MAX; + max_scf = SHRT_MIN; + + for (sfb = 0; sfb < sfb_count; sfb++) { + if (ptr_scf[sfb] != SHRT_MIN) { + min_scf = MIN(min_scf, ptr_scf[sfb]); + + max_scf = MAX(max_scf, ptr_scf[sfb]); + } + } + + if (max_scf != SHRT_MIN && max_scf <= min_scf + MAX_SCF_DELTA) { + scf_act = max_scf; + + do { + scf_act--; + + memcpy(scf_temp, ptr_scf, MAX_NUM_GROUPED_SFB * sizeof(WORD16)); + + stop_sfb = 0; + + do { + sfb = stop_sfb; + + while (sfb < sfb_count && (ptr_scf[sfb] == SHRT_MIN || ptr_scf[sfb] <= scf_act)) { + sfb++; + } + + start_sfb = sfb; + + sfb++; + + while (sfb < sfb_count && (ptr_scf[sfb] == SHRT_MIN || ptr_scf[sfb] > scf_act)) { + sfb++; + } + + stop_sfb = sfb; + + possible_region_found = 0; + + if (start_sfb < sfb_count) { + possible_region_found = 1; + + for (sfb = start_sfb; sfb < stop_sfb; sfb++) { + if (ptr_scf[sfb] != SHRT_MIN) { + if (scf_act < ptr_min_scf[sfb]) { + possible_region_found = 0; + break; + } + } + } + } + + if (possible_region_found) { + for (sfb = start_sfb; sfb < stop_sfb; sfb++) { + if (scf_temp[sfb] != SHRT_MIN) { + scf_temp[sfb] = scf_act; + } + } + + delta_scf_bits = + iusace_count_scf_bits_diff(ptr_scf, scf_temp, sfb_count, start_sfb, stop_sfb); + + delta_spec_pe = + iusace_calc_spec_pe_diff(pstr_psy_out, ptr_scf, scf_temp, ptr_sfb_const_pe_part, + ptr_sfb_form_fac, ptr_sfb_num_lines, start_sfb, stop_sfb); + + delta_pe_new = delta_pe + (FLOAT32)delta_scf_bits + delta_spec_pe; + + if (delta_pe_new < (FLOAT32)10.0f) { + prev_dist_sum = new_dist_sum = 0.0f; + + for (sfb = start_sfb; sfb < stop_sfb; sfb++) { + if (scf_temp[sfb] != SHRT_MIN) { + prev_dist_sum += ptr_sfb_dist[sfb]; + + sfb_width = pstr_psy_out->sfb_offsets[sfb + 1] - pstr_psy_out->sfb_offsets[sfb]; + + sfb_offs = pstr_psy_out->sfb_offsets[sfb]; + + sfb_dist_new[sfb] = + iusace_calc_sfb_dist(ptr_mdct_spec_float + sfb_offs, ptr_exp_spec + sfb_offs, + ptr_quant_spec_temp + sfb_offs, sfb_width, scf_act); + + if (sfb_dist_new[sfb] > pstr_psy_out->ptr_sfb_thr[sfb]) { + new_dist_sum = (FLOAT32)2.0f * prev_dist_sum; + break; + } + + new_dist_sum += sfb_dist_new[sfb]; + } + } + + if (new_dist_sum < prev_dist_sum) { + delta_pe = delta_pe_new; + + for (sfb = start_sfb; sfb < stop_sfb; sfb++) { + if (ptr_scf[sfb] != SHRT_MIN) { + sfb_width = pstr_psy_out->sfb_offsets[sfb + 1] - pstr_psy_out->sfb_offsets[sfb]; + + sfb_offs = pstr_psy_out->sfb_offsets[sfb]; + ptr_scf[sfb] = scf_act; + ptr_sfb_dist[sfb] = sfb_dist_new[sfb]; + + for (j = sfb_offs; j < sfb_offs + sfb_width; j++) { + ptr_quant_spec[j] = ptr_quant_spec_temp[j]; + + if (ptr_mdct_spec_float[j] < 0.0f) { + ptr_quant_spec[j] = -ptr_quant_spec[j]; + } + } + } + } + } + } + } + + } while (stop_sfb <= sfb_count); + + } while (scf_act > min_scf); + } + return; +} + +VOID iusace_estimate_scfs_chan(ia_psy_mod_out_data_struct *pstr_psy_out, + ia_qc_out_chan_struct *str_qc_out_chan, WORD32 num_channels, + WORD32 chn, iusace_scratch_mem *pstr_scratch) { + WORD16 *ptr_scalefactor; + WORD32 *global_gain; + FLOAT32 *p_sfb_form_factor; + FLOAT32 *p_sfb_num_relevant_lines; + WORD16 *ptr_quant_spec; + WORD32 i, ch, j, idx = 0; + FLOAT32 thresh, energy, energy_part, thr_part; + FLOAT32 scf_float; + WORD16 scf_int = 0, min_scf = 0, max_scf = 0; + FLOAT64 max_spec = 0.0f; + WORD16 min_sf_max_quant[MAX_NUM_GROUPED_SFB] = {0}; + pUWORD8 ptr_scratch = pstr_scratch->ptr_fd_scratch; + FLOAT32 *ptr_sfb_dist = (FLOAT32 *)ptr_scratch; + ptr_scratch += MAX_NUM_GROUPED_SFB * sizeof(ptr_sfb_dist[0]); + WORD16 min_calc_scf[MAX_NUM_GROUPED_SFB] = {0}; + + WORD16 *ptr_quant_spec_temp = pstr_scratch->p_adjthr_quant_spec_temp; + FLOAT32 *ptr_exp_spec = pstr_scratch->p_adjthr_ptr_exp_spec; + FLOAT32 *ptr_mdct_spec_float = pstr_scratch->p_adjthr_mdct_spec_float; + FLOAT32 *sfb_const_pe_part = (FLOAT32 *)ptr_scratch; + + FLOAT32 **ptr_sfb_form_factor = &pstr_scratch->ptr_sfb_form_fac[0]; + FLOAT32 **ptr_sfb_num_relevant_lines = &pstr_scratch->ptr_sfb_num_relevant_lines[0]; + + ptr_scratch += MAX_NUM_GROUPED_SFB * sizeof(sfb_const_pe_part[0]); + + memset(ptr_quant_spec_temp, 0, FRAME_LEN_LONG * sizeof(WORD16)); + memset(ptr_mdct_spec_float, 0, FRAME_LEN_LONG * sizeof(FLOAT32)); + memset(ptr_exp_spec, 0, FRAME_LEN_LONG * sizeof(FLOAT32)); + memset(ptr_sfb_dist, 0, MAX_NUM_GROUPED_SFB * sizeof(FLOAT32)); + for (ch = chn; ch < chn + num_channels; ch++) { + ia_psy_mod_out_data_struct *ptr_psy_out = &pstr_psy_out[ch]; + str_qc_out_chan[idx].global_gain = 0; + + memset(str_qc_out_chan[idx].scalefactor, 0, + sizeof(str_qc_out_chan[idx].scalefactor[0]) * pstr_psy_out[ch].sfb_count); + memset(str_qc_out_chan[idx].quant_spec, 0, + sizeof(str_qc_out_chan[idx].quant_spec[0]) * FRAME_LEN_LONG); + + ptr_scalefactor = str_qc_out_chan[idx].scalefactor; + global_gain = &str_qc_out_chan[idx].global_gain; + p_sfb_form_factor = &ptr_sfb_form_factor[idx][0]; + p_sfb_num_relevant_lines = &ptr_sfb_num_relevant_lines[idx][0]; + ptr_quant_spec = str_qc_out_chan[idx].quant_spec; + for (i = 0; i < ptr_psy_out->sfb_count; i++) { + thresh = ptr_psy_out->ptr_sfb_thr[i]; + energy = ptr_psy_out->ptr_sfb_energy[i]; + max_spec = 0.0; + + for (j = ptr_psy_out->sfb_offsets[i]; j < ptr_psy_out->sfb_offsets[i + 1]; j++) { + max_spec = MAX(max_spec, fabs(ptr_psy_out->ptr_spec_coeffs[j])); + } + + ptr_scalefactor[i] = MIN_SHRT_VAL; + min_sf_max_quant[i] = MIN_SHRT_VAL; + + if ((max_spec > 0.0) && (energy > thresh) && (p_sfb_form_factor[i] != MIN_FLT_VAL)) { + energy_part = (FLOAT32)log10(p_sfb_form_factor[i]); + + thr_part = (FLOAT32)log10(6.75 * thresh + MIN_FLT_VAL); + scf_float = 8.8585f * (thr_part - energy_part); + scf_int = (WORD16)floor(scf_float); + min_sf_max_quant[i] = (WORD16)ceil(C1_SF + C2_SF * log(max_spec)); + scf_int = MAX(scf_int, min_sf_max_quant[i]); + + for (j = 0; j < ptr_psy_out->sfb_offsets[i + 1] - ptr_psy_out->sfb_offsets[i]; j++) { + ptr_exp_spec[ptr_psy_out->sfb_offsets[i] + j] = + (FLOAT32)(ptr_psy_out->ptr_spec_coeffs[ptr_psy_out->sfb_offsets[i] + j]); + ptr_mdct_spec_float[ptr_psy_out->sfb_offsets[i] + j] = + (FLOAT32)(ptr_psy_out->ptr_spec_coeffs[ptr_psy_out->sfb_offsets[i] + j]); + } + + iusace_calculate_exp_spec(ptr_psy_out->sfb_offsets[i + 1] - ptr_psy_out->sfb_offsets[i], + ptr_exp_spec + ptr_psy_out->sfb_offsets[i], + ptr_mdct_spec_float + ptr_psy_out->sfb_offsets[i]); + + scf_int = iusace_improve_scf( + ptr_mdct_spec_float + ptr_psy_out->sfb_offsets[i], + ptr_exp_spec + ptr_psy_out->sfb_offsets[i], + ptr_quant_spec + ptr_psy_out->sfb_offsets[i], + ptr_quant_spec_temp + ptr_psy_out->sfb_offsets[i], + ptr_psy_out->sfb_offsets[i + 1] - ptr_psy_out->sfb_offsets[i], thresh, scf_int, + min_sf_max_quant[i], &ptr_sfb_dist[i], &min_calc_scf[i]); + + ptr_scalefactor[i] = scf_int; + } + } + + for (i = 0; i < ptr_psy_out->sfb_count; i++) { + sfb_const_pe_part[i] = MIN_FLT_VAL; + } + + iusace_assimilate_single_scf(ptr_psy_out, ptr_exp_spec, ptr_quant_spec, ptr_quant_spec_temp, + ptr_scalefactor, min_sf_max_quant, ptr_sfb_dist, + sfb_const_pe_part, p_sfb_form_factor, p_sfb_num_relevant_lines, + min_calc_scf, ptr_mdct_spec_float); + + iusace_assimilate_multiple_scf(ptr_psy_out, ptr_exp_spec, ptr_quant_spec, ptr_quant_spec_temp, + ptr_scalefactor, min_sf_max_quant, ptr_sfb_dist, + sfb_const_pe_part, p_sfb_form_factor, p_sfb_num_relevant_lines, + ptr_mdct_spec_float, ptr_scratch); + + max_scf = MIN_SHRT_VAL; + min_scf = MAX_SHRT_VAL; + for (i = 0; i < ptr_psy_out->sfb_count; i++) { + if (max_scf < ptr_scalefactor[i]) { + max_scf = ptr_scalefactor[i]; + } + if ((ptr_scalefactor[i] != MIN_SHRT_VAL) && (min_scf > ptr_scalefactor[i])) { + min_scf = ptr_scalefactor[i]; + } + } + + for (i = 0; i < pstr_psy_out[ch].sfb_count; i++) { + if ((ptr_scalefactor[i] != MIN_SHRT_VAL) && + (min_scf + MAX_SCF_DELTA) < ptr_scalefactor[i]) { + ptr_scalefactor[i] = min_scf + MAX_SCF_DELTA; + + iusace_calc_sfb_dist(ptr_mdct_spec_float + ptr_psy_out->sfb_offsets[i], + ptr_exp_spec + ptr_psy_out->sfb_offsets[i], + ptr_quant_spec + ptr_psy_out->sfb_offsets[i], + ptr_psy_out->sfb_offsets[i + 1] - ptr_psy_out->sfb_offsets[i], + ptr_scalefactor[i]); + } + } + + max_scf = MIN((min_scf + MAX_SCF_DELTA), max_scf); + + if (max_scf > MIN_SHRT_VAL) { + *global_gain = max_scf; + for (i = 0; i < ptr_psy_out->sfb_count; i++) { + if (ptr_scalefactor[i] == MIN_SHRT_VAL) { + ptr_scalefactor[i] = 0; + memset( + &ptr_psy_out->ptr_spec_coeffs[ptr_psy_out->sfb_offsets[i]], 0, + (ptr_psy_out->sfb_offsets[i + 1] - ptr_psy_out->sfb_offsets[i]) * sizeof(FLOAT64)); + } else { + ptr_scalefactor[i] = max_scf - ptr_scalefactor[i]; + } + } + } else { + *global_gain = 0; + for (i = 0; i < ptr_psy_out->sfb_count; i++) { + ptr_scalefactor[i] = 0; + memset(&ptr_psy_out->ptr_spec_coeffs[ptr_psy_out->sfb_offsets[i]], 0, + (ptr_psy_out->sfb_offsets[i + 1] - ptr_psy_out->sfb_offsets[i]) * sizeof(FLOAT64)); + } + } + idx++; + } + + return; +} diff --git a/encoder/ixheaace_fd_qc_util.c b/encoder/ixheaace_fd_qc_util.c new file mode 100644 index 0000000..ecc822c --- /dev/null +++ b/encoder/ixheaace_fd_qc_util.c @@ -0,0 +1,164 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include +#include +#include "iusace_type_def.h" +#include "iusace_cnst.h" +#include "iusace_bitbuffer.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_api.h" +#include "impd_drc_uni_drc_eq.h" +#include "impd_drc_uni_drc_filter_bank.h" +#include "impd_drc_gain_enc.h" +#include "impd_drc_struct_def.h" + +#include "ixheaace_memory_standards.h" +#include "iusace_tns_usac.h" +#include "iusace_psy_mod.h" +#include "iusace_config.h" +#include "ixheaace_adjust_threshold_data.h" +#include "iusace_fd_qc_util.h" +#include "iusace_fd_qc_adjthr.h" + +VOID iusace_qc_create(ia_qc_main_struct *pstr_qc_main) { + WORD32 i = 0; + memset(pstr_qc_main, 0, sizeof(ia_qc_main_struct)); + + for (i = 0; i < 2; i++) { + memset(pstr_qc_main->str_qc_out.str_qc_out_chan[i].quant_spec, 0, + sizeof(WORD16) * FRAME_LEN_LONG); + memset(pstr_qc_main->str_qc_out.str_qc_out_chan[i].scalefactor, 0, + sizeof(WORD16) * FRAME_LEN_LONG); + } + return; +} + +VOID iusace_qc_init(ia_qc_data_struct *pstr_qc_data, const WORD32 max_bits, WORD32 sample_rate, + WORD32 bw_limit, WORD32 channels, WORD32 ccfl) { + FLOAT32 mean_pe; + pstr_qc_data->tot_avg_bits = pstr_qc_data->avg_bits; + pstr_qc_data->static_bits = 1; + pstr_qc_data->avg_bits = (pstr_qc_data->avg_bits - pstr_qc_data->static_bits); + pstr_qc_data->max_bits = channels * max_bits; + pstr_qc_data->max_bitres_bits = channels * max_bits - pstr_qc_data->tot_avg_bits; + pstr_qc_data->max_bitres_bits = + pstr_qc_data->max_bitres_bits - (pstr_qc_data->max_bitres_bits % 8); + pstr_qc_data->bit_res_lvl = pstr_qc_data->max_bitres_bits; + pstr_qc_data->padding = sample_rate; + + pstr_qc_data->max_bit_fac = + (FLOAT32)channels * (max_bits - 744) / + (FLOAT32)(pstr_qc_data->tot_avg_bits ? pstr_qc_data->tot_avg_bits : 1); + mean_pe = 10.0f * ccfl * bw_limit / (sample_rate / 2.0f); + + iusace_adj_thr_init(&pstr_qc_data->str_adj_thr_ele, mean_pe, + (channels > 0) ? pstr_qc_data->ch_bitrate / channels : 0); + + return; +} + +static WORD32 iusace_calc_frame_len(WORD32 bit_rate, WORD32 sample_rate, WORD32 mode, + WORD32 ccfl) { + WORD32 result; + + result = ((ccfl) >> 3) * (bit_rate); + switch (mode) { + case FRAME_LEN_BYTES_MODULO: + result %= sample_rate; + break; + case FRAME_LEN_BYTES_INT: + result /= sample_rate; + break; + } + + return (result); +} + +static WORD32 iusace_get_frame_padding(WORD32 bit_rate, WORD32 sample_rate, WORD32 *padding, + WORD32 ccfl) { + WORD32 padding_on = 0; + WORD32 difference; + + difference = iusace_calc_frame_len(bit_rate, sample_rate, FRAME_LEN_BYTES_MODULO, ccfl); + + *padding -= difference; + + if (*padding <= 0) { + padding_on = 1; + *padding += sample_rate; + } + + return padding_on; +} + +VOID iusace_adj_bitrate(ia_qc_data_struct *pstr_qc_data, WORD32 bit_rate, WORD32 sample_rate, + WORD32 ccfl) { + WORD32 padding_on; + WORD32 frame_len; + WORD32 code_bits; + WORD32 code_bits_prev; + WORD32 total_bits = 0; + + padding_on = iusace_get_frame_padding(bit_rate, sample_rate, &pstr_qc_data->padding, ccfl); + frame_len = + padding_on + iusace_calc_frame_len(bit_rate, sample_rate, FRAME_LEN_BYTES_INT, ccfl); + + frame_len <<= 3; + code_bits_prev = pstr_qc_data->tot_avg_bits - pstr_qc_data->static_bits; + code_bits = frame_len - pstr_qc_data->static_bits; + + if (code_bits != code_bits_prev) { + pstr_qc_data->avg_bits = (WORD32)code_bits; + total_bits += pstr_qc_data->avg_bits; + pstr_qc_data->avg_bits += code_bits - total_bits; + } + + pstr_qc_data->tot_avg_bits = frame_len; + + return; +} + +WORD32 iusace_calc_max_val_in_sfb(WORD32 sfb_count, WORD32 max_sfb_per_grp, WORD32 sfb_per_group, + WORD32 *ptr_sfb_offset, WORD16 *ptr_quant_spec) { + WORD32 sfb; + WORD32 max = 0; + WORD32 sfb_offs; + + for (sfb_offs = 0; sfb_offs < sfb_count; sfb_offs += sfb_per_group) { + for (sfb = 0; sfb < max_sfb_per_grp; sfb++) { + WORD32 line; + WORD32 local_max = 0; + for (line = ptr_sfb_offset[sfb + sfb_offs]; line < ptr_sfb_offset[sfb + sfb_offs + 1]; + line++) { + if (abs(ptr_quant_spec[line]) > local_max) { + local_max = abs(ptr_quant_spec[line]); + } + } + if (local_max > max) { + max = local_max; + } + } + } + + return max; +} diff --git a/encoder/ixheaace_fd_quant.c b/encoder/ixheaace_fd_quant.c new file mode 100644 index 0000000..528c66a --- /dev/null +++ b/encoder/ixheaace_fd_quant.c @@ -0,0 +1,672 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include +#include "iusace_type_def.h" +#include "ixheaac_error_standards.h" +#include "ixheaace_error_codes.h" +#include "ixheaace_mps_common_define.h" +#include "iusace_cnst.h" +#include "iusace_block_switch_const.h" +#include "iusace_bitbuffer.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_api.h" +#include "impd_drc_uni_drc_eq.h" +#include "impd_drc_uni_drc_filter_bank.h" +#include "impd_drc_gain_enc.h" +#include "impd_drc_struct_def.h" + +#include "ixheaace_memory_standards.h" +#include "iusace_tns_usac.h" +#include "iusace_psy_mod.h" +#include "iusace_config.h" +#include "iusace_ms.h" +#include "ixheaace_adjust_threshold_data.h" +#include "iusace_fd_qc_util.h" +#include "iusace_arith_enc.h" +#include "iusace_fd_quant.h" +#include "iusace_signal_classifier.h" +#include "iusace_block_switch_struct_def.h" +#include "ixheaace_sbr_header.h" +#include "ixheaace_config.h" +#include "ixheaace_asc_write.h" +#include "iusace_main.h" +#include "iusace_write_bitstream.h" +#include "ixheaace_nf.h" +#include "iusace_fd_qc_adjthr.h" +#include "iusace_block_switch_const.h" +#include "iusace_rom.h" +#include "ixheaace_cplx_pred.h" + +#if DEBUG_DUMP +extern FILE *out_file; +#endif + +static WORD32 iusace_window_shape[5] = {WIN_SEL_1, WIN_SEL_0, WIN_SEL_0, WIN_SEL_1, WIN_SEL_0}; + +static WORD32 iusace_count_ms_bits(WORD32 sfb_count, WORD32 sfb_per_grp, WORD32 max_sfb_per_grp) { + WORD32 ms_bits = 0, sfb_offs, sfb; + for (sfb_offs = 0; sfb_offs < sfb_count; sfb_offs += sfb_per_grp) { + for (sfb = 0; sfb < max_sfb_per_grp; sfb++) { + ms_bits++; + } + } + return (ms_bits); +} + +static WORD32 iusace_count_static_bits(ia_usac_data_struct *ptr_usac_data, + ia_usac_encoder_config_struct *ptr_usac_config, + ia_sfb_params_struct *pstr_sfb_params, + ia_psy_mod_out_data_struct *pstr_psy_out, WORD32 channels, + WORD32 chn, WORD32 usac_independency_flag, WORD32 ele_id) { + WORD32 ms_mask = ptr_usac_data->str_ms_info[chn].ms_mask; + WORD32 noise_filling = ptr_usac_data->noise_filling[ele_id]; + WORD32 stat_bits = 0, i; + WORD32 tns_active = 0, tns_present_both = 0; + WORD32 max_sfb = pstr_psy_out[chn].max_sfb_per_grp; + (VOID) ptr_usac_config; + + if (channels == 1) { + stat_bits += 1; // core mode + stat_bits += 1; // tns active + + switch (pstr_psy_out[chn].window_sequence) { + case ONLY_LONG_SEQUENCE: + case LONG_START_SEQUENCE: + case LONG_STOP_SEQUENCE: + stat_bits += SI_ICS_INFO_BITS_LONG; + break; + case EIGHT_SHORT_SEQUENCE: + stat_bits += SI_ICS_INFO_BITS_SHORT; + break; + } + } else { + stat_bits += 2; // core mode + stat_bits += 2; // tns and common window + + switch (pstr_psy_out[chn].window_sequence) { + case ONLY_LONG_SEQUENCE: + case LONG_START_SEQUENCE: + case LONG_STOP_SEQUENCE: + stat_bits += SI_ICS_INFO_BITS_LONG; + break; + case EIGHT_SHORT_SEQUENCE: + stat_bits += SI_ICS_INFO_BITS_SHORT; + break; + } + + stat_bits += 1; // common_max_sfb + stat_bits += SI_CPE_MS_MASK_BITS; + + if (ms_mask != 3) { + if (ms_mask == 1) { + stat_bits += iusace_count_ms_bits(pstr_psy_out[chn].sfb_count, + pstr_psy_out[chn].sfb_per_group, max_sfb); + } + } else { + stat_bits += iusace_write_cplx_pred_data( + NULL, pstr_sfb_params->num_window_groups[chn], max_sfb, + ptr_usac_data->complex_coef[chn], ptr_usac_data->pred_coef_re[chn], + ptr_usac_data->pred_coef_im[chn], iusace_huffman_code_table, usac_independency_flag, + ptr_usac_data->pred_dir_idx[chn], ptr_usac_data->cplx_pred_used[chn], + ptr_usac_data->cplx_pred_all[chn], ptr_usac_data->temp_pred_coef_re_prev[chn], + ptr_usac_data->temp_pred_coef_im_prev[chn], &ptr_usac_data->delta_code_time[chn]); + } + + if (ptr_usac_data->pstr_tns_info[chn] != NULL && + ptr_usac_data->pstr_tns_info[chn + 1] != NULL) { + tns_active = ptr_usac_data->pstr_tns_info[chn]->tns_data_present || + ptr_usac_data->pstr_tns_info[chn + 1]->tns_data_present; + tns_present_both = ptr_usac_data->pstr_tns_info[chn]->tns_data_present && + ptr_usac_data->pstr_tns_info[chn + 1]->tns_data_present; + } + if (tns_active) { + stat_bits += 1; // common_tns + + stat_bits += 1; // tns_present_both + + if (!tns_present_both) { + stat_bits += 1; // tns_data_present1 + } + } + } + + for (i = chn; i < chn + channels; i++) { + stat_bits += 8; // global_gain + + if (noise_filling) { + stat_bits += 8; + } + } + + for (i = chn; i < chn + channels; i++) { + if (ptr_usac_data->pstr_tns_info[i] != NULL && + ptr_usac_data->pstr_tns_info[i]->tns_data_present == 1) { + stat_bits += iusace_write_tns_data(NULL, ptr_usac_data->pstr_tns_info[i], + pstr_psy_out[i].window_sequence, 0); + } + + if (!usac_independency_flag) { + stat_bits += 1; // arith_reset_flag + } + + stat_bits += 1; // fac_data_present + stat_bits += ptr_usac_data->str_scratch.ptr_num_fac_bits[i]; + } + + stat_bits += ptr_usac_data->num_sbr_bits; + + return stat_bits; +} + +static VOID iusace_sort_for_grouping(WORD32 *sfb_offset, const WORD32 *sfb_width_table, + FLOAT64 *ptr_scratch, FLOAT64 *ptr_spec, + WORD32 num_window_groups, const WORD32 *window_group_length, + WORD32 nr_of_sfb, WORD32 ccfl) { + WORD32 i, j, ii; + WORD32 index = 0; + WORD32 group_offset = 0; + WORD32 k = 0; + WORD32 frame_len_short = (ccfl * FRAME_LEN_SHORT_128) / FRAME_LEN_LONG; + + sfb_offset[k] = 0; + for (k = 1; k < nr_of_sfb + 1; k++) { + sfb_offset[k] = sfb_offset[k - 1] + sfb_width_table[k - 1]; + } + + index = 0; + group_offset = 0; + for (i = 0; i < num_window_groups; i++) { + for (k = 0; k < nr_of_sfb; k++) { + for (j = 0; j < window_group_length[i]; j++) { + for (ii = 0; ii < sfb_width_table[k]; ii++) { + ptr_scratch[index++] = + ptr_spec[ii + sfb_offset[k] + frame_len_short * j + group_offset]; + } + } + } + group_offset += frame_len_short * window_group_length[i]; + } + + memcpy(ptr_spec, ptr_scratch, ccfl * sizeof(ptr_spec[0])); + + index = 0; + sfb_offset[index++] = 0; + for (i = 0; i < num_window_groups; i++) { + for (k = 0; k < nr_of_sfb; k++) { + sfb_offset[index] = sfb_offset[index - 1] + sfb_width_table[k] * window_group_length[i]; + index++; + } + } + + return; +} + +static VOID iusace_degroup_int(const WORD32 *ptr_grouped_sfb_offsets, WORD32 sfb_per_group, + WORD32 *ptr_scratch, WORD32 *ptr_spec, WORD32 num_window_groups, + const WORD32 *window_group_length, WORD32 ccfl) + +{ + WORD32 i, j, k, n; + WORD32 index, group_offset; + WORD32 loop1, loop2; + WORD32 frame_len_short = (ccfl * FRAME_LEN_SHORT_128) / FRAME_LEN_LONG; + index = 0; + group_offset = 0; + + memset(ptr_scratch, 0, ccfl * sizeof(WORD32)); + + for (i = 0; i < num_window_groups; i++) { + for (j = 0; j < sfb_per_group; j++) { + WORD32 idx = i * sfb_per_group + j; + loop1 = ((ptr_grouped_sfb_offsets[idx + 1] - ptr_grouped_sfb_offsets[idx]) / + window_group_length[i]); + + for (k = 0; k < window_group_length[i]; k++) { + loop2 = ((ptr_grouped_sfb_offsets[idx] - group_offset) / window_group_length[i]) + + frame_len_short * k + group_offset; + + for (n = 0; n < loop1; n++) { + ptr_scratch[n + loop2] = ptr_spec[index++]; + } + } + } + group_offset += frame_len_short * window_group_length[i]; + } + + memcpy(ptr_spec, ptr_scratch, ccfl * sizeof(WORD32)); + + return; +} + +IA_ERRORCODE iusace_stereo_proc(ia_sfb_params_struct *pstr_sfb_prms, + WORD32 usac_independancy_flag, ia_usac_data_struct *ptr_usac_data, + ia_usac_encoder_config_struct *ptr_usac_config, WORD32 chn) { + IA_ERRORCODE err_code; + WORD32 i = 0; + WORD32 j = 0; + iusace_scratch_mem *pstr_scratch = &ptr_usac_data->str_scratch; + ia_psy_mod_data_struct *pstr_psy_data = ptr_usac_data->str_psy_mod.str_psy_data; + ia_psy_mod_out_data_struct *pstr_psy_out = ptr_usac_data->str_psy_mod.str_psy_out_data; + WORD32 *ptr_num_sfb = pstr_sfb_prms->num_sfb; + WORD32 *ptr_num_window_groups = pstr_sfb_prms->num_window_groups; + WORD32 ccfl = ptr_usac_config->ccfl; + ia_ms_info_struct *pstr_ms_info = &ptr_usac_data->str_ms_info[chn]; + + FLOAT64 tmp = 0.0f; + FLOAT32 nrg_mid = 0.0f, nrg_side = 0.0f, nrg_left = 0.0f, nrg_right = 0.0f; + FLOAT64 *ptr_scratch_spec = pstr_scratch->p_quant_spectrum_spec_scratch; + FLOAT32 ratio_mid = 0.0f, ratio_side = 0.0f; + FLOAT32 eps = 1.0e-6f; + /* Save a copy of left and right channel MDCT spectra before they are modified */ + memcpy(ptr_usac_data->left_chan_save[chn], ptr_usac_data->spectral_line_vector[chn], + ccfl * sizeof(FLOAT64)); + memcpy(ptr_usac_data->right_chan_save[chn], ptr_usac_data->spectral_line_vector[chn + 1], + ccfl * sizeof(FLOAT64)); + + if (ptr_usac_config->cmplx_pred_flag == 1) { + /* Refinement - decision on whether to use complex prediction or MS */ + for (i = 0; i < ccfl; i++) { + tmp = ptr_usac_data->spectral_line_vector[chn][i]; + ptr_scratch_spec[i] = 0.5f * (ptr_usac_data->spectral_line_vector[chn][i] + + ptr_usac_data->spectral_line_vector[chn + 1][i]); + ptr_scratch_spec[ccfl + i] = 0.5f * (tmp - ptr_usac_data->spectral_line_vector[chn + 1][i]); + } + + for (i = 0; i < ccfl; i++) { + nrg_mid += (FLOAT32)(ptr_scratch_spec[i] * ptr_scratch_spec[i]); + nrg_side += (FLOAT32)(ptr_scratch_spec[ccfl + i] * ptr_scratch_spec[ccfl + i]); + nrg_left += (FLOAT32)(ptr_usac_data->spectral_line_vector[chn][i] * + ptr_usac_data->spectral_line_vector[chn][i]); + nrg_right += (FLOAT32)(ptr_usac_data->spectral_line_vector[chn + 1][i] * + ptr_usac_data->spectral_line_vector[chn + 1][i]); + } + + ratio_mid = nrg_mid / (MAX(nrg_left, nrg_right) + eps); + ratio_side = nrg_side / (MAX(nrg_left, nrg_right) + eps); + + if (ratio_mid >= 0.8f || ratio_side >= 0.8f || nrg_mid == 0.f || nrg_side == 0.f) { + pstr_ms_info->ms_mask = 0; + } else { + pstr_ms_info->ms_mask = 3; + } + } + + if (pstr_ms_info->ms_mask != 3) { + WORD32 idx = 0; + WORD32 sfb; + + for (sfb = 0; sfb < ptr_num_sfb[chn]; sfb++) { + ptr_usac_data->pred_coef_re_prev[chn][sfb] = 0; + ptr_usac_data->pred_coef_im_prev[chn][sfb] = 0; + ptr_usac_data->temp_pred_coef_re_prev[chn][sfb] = 0; + ptr_usac_data->temp_pred_coef_im_prev[chn][sfb] = 0; + } + + memset(ptr_usac_data->str_ms_info[chn].ms_used, 0, + MAX_SFB_LONG * MAX_SHORT_WINDOWS * sizeof(WORD32)); + + iusace_ms_apply(pstr_psy_data, ptr_usac_data->spectral_line_vector[chn], + ptr_usac_data->spectral_line_vector[chn + 1], + &ptr_usac_data->str_ms_info[chn].ms_mask, + ptr_usac_data->str_ms_info[chn].ms_used, + ptr_num_window_groups[chn] * ptr_num_sfb[chn], ptr_num_sfb[chn], + pstr_psy_out[chn].max_sfb_per_grp, pstr_sfb_prms->grouped_sfb_offset[chn], + chn, ptr_usac_config->cmplx_pred_flag == 1 ? ptr_scratch_spec : NULL); + + for (i = 0; i < ptr_num_window_groups[chn]; i++) { + for (j = 0; j < ptr_num_sfb[chn]; j++) { + pstr_psy_out[chn].ms_used[idx++] = ptr_usac_data->str_ms_info[chn].ms_used[i][j]; + } + } + } else { + /* Reset buffer to zero */ + for (WORD32 group = 0; group < MAX_SHORT_WINDOWS; group++) { + memset(ptr_usac_data->cplx_pred_used[chn][group], 0, MAX_SFB_LONG * sizeof(WORD32)); + } + + ptr_usac_data->cplx_pred_all[chn] = 1; /* Disable bandwise switching to L/R */ + for (i = 0; i < ptr_num_window_groups[chn]; i++) { + for (j = 0; j < ptr_num_sfb[chn]; j += 2) { + ptr_usac_data->cplx_pred_used[chn][i][j] = 1; + if ((j + 1) < ptr_num_sfb[chn]) { + ptr_usac_data->cplx_pred_used[chn][i][j + 1] = ptr_usac_data->cplx_pred_used[chn][i][j]; + } + } + } + + err_code = iusace_cplx_pred_proc( + ptr_usac_data, ptr_usac_config, usac_independancy_flag, pstr_sfb_prms, chn, pstr_psy_data, + pstr_sfb_prms->grouped_sfb_offset[chn], pstr_scratch->p_cmpx_mdct_temp_buf, + ptr_scratch_spec, nrg_mid, nrg_side); + if (err_code != IA_NO_ERROR) { + return err_code; + } + } + return IA_NO_ERROR; +} + +IA_ERRORCODE iusace_grouping(ia_sfb_params_struct *pstr_sfb_prms, WORD32 num_chans, + ia_usac_data_struct *ptr_usac_data, + ia_usac_encoder_config_struct *ptr_usac_config, WORD32 chn, + WORD32 ele_id) { + WORD32 i = 0, grp, sfb, wnd; + WORD32 j = 0; + WORD32 k; + WORD32 ch; + ia_psy_mod_struct *pstr_psy_config = &ptr_usac_data->str_psy_mod; + ia_psy_mod_data_struct *pstr_psy_data = ptr_usac_data->str_psy_mod.str_psy_data; + WORD32 *ptr_window_sequence = pstr_sfb_prms->window_sequence; + WORD32 *ptr_num_sfb = pstr_sfb_prms->num_sfb; + WORD32 *ptr_num_window_groups = pstr_sfb_prms->num_window_groups; + ia_psy_mod_out_data_struct *pstr_psy_out = ptr_usac_data->str_psy_mod.str_psy_out_data; + + for (ch = chn; ch < chn + num_chans; ch++) { + if (ptr_window_sequence[ch] == EIGHT_SHORT_SEQUENCE) { + iusace_sort_for_grouping( + pstr_sfb_prms->grouped_sfb_offset[ch], pstr_sfb_prms->sfb_width_table[ch], + ptr_usac_data->str_scratch.p_sort_grouping_scratch, + ptr_usac_data->spectral_line_vector[ch], ptr_num_window_groups[ch], + pstr_sfb_prms->window_group_length[ch], ptr_num_sfb[ch], ptr_usac_config->ccfl); + } else if ((ptr_window_sequence[ch] == ONLY_LONG_SEQUENCE) || + (ptr_window_sequence[ch] == LONG_START_SEQUENCE) || + (ptr_window_sequence[ch] == LONG_STOP_SEQUENCE) || + (ptr_window_sequence[ch] == STOP_START_SEQUENCE)) { + pstr_sfb_prms->grouped_sfb_offset[ch][0] = 0; + k = 0; + for (i = 0; i < ptr_num_sfb[ch]; i++) { + pstr_sfb_prms->grouped_sfb_offset[ch][i] = k; + k += pstr_sfb_prms->sfb_width_table[ch][i]; + } + pstr_sfb_prms->grouped_sfb_offset[ch][i] = k; + } else { + return -1; + } + } + + for (ch = chn; ch < chn + num_chans; ch++) { + if (pstr_psy_data[ch].window_sequence == 2) { + i = 0; + for (grp = 0; grp < ptr_num_window_groups[ch]; grp++) { + for (sfb = 0; sfb < ptr_num_sfb[ch]; sfb++) { + pstr_psy_out[ch].sfb_min_snr[i++] = + pstr_psy_config->str_psy_short_config[ele_id].sfb_min_snr[sfb]; + } + } + wnd = 0; + i = 0; + for (grp = 0; grp < ptr_num_window_groups[ch]; grp++) { + for (sfb = 0; sfb < ptr_num_sfb[ch]; sfb++) { + FLOAT32 threshold = pstr_psy_data[ch].sfb_thr_short[wnd][sfb]; + FLOAT32 energy = pstr_psy_data[ch].sfb_energy_short[wnd][sfb]; + FLOAT32 energy_ms = pstr_psy_data[ch].ptr_sfb_energy_short_ms[wnd][sfb]; + FLOAT32 spread_energy = pstr_psy_data[ch].sfb_spreaded_energy_short[wnd][sfb]; + for (j = 1; j < pstr_sfb_prms->window_group_length[ch][grp]; j++) { + threshold = threshold + pstr_psy_data[ch].sfb_thr_short[wnd + j][sfb]; + energy = energy + pstr_psy_data[ch].sfb_energy_short[wnd + j][sfb]; + spread_energy = + spread_energy + pstr_psy_data[ch].sfb_spreaded_energy_short[wnd + j][sfb]; + energy_ms = energy_ms + pstr_psy_data[ch].ptr_sfb_energy_short_ms[wnd + j][sfb]; + } + pstr_psy_data[ch].ptr_sfb_thr_long[i] = threshold; + pstr_psy_data[ch].ptr_sfb_energy_long[i] = energy; + pstr_psy_data[ch].ptr_sfb_energy_long_ms[i] = energy_ms; + pstr_psy_data[ch].ptr_sfb_spreaded_energy_long[i++] = spread_energy; + } + wnd += pstr_sfb_prms->window_group_length[ch][grp]; + } + } else { + for (sfb = 0; sfb < ptr_num_sfb[ch]; sfb++) { + pstr_psy_out[ch].sfb_min_snr[sfb] = + pstr_psy_config->str_psy_long_config[ele_id].sfb_min_snr[sfb]; + } + } + } + return 0; +} + +IA_ERRORCODE iusace_quantize_spec(ia_sfb_params_struct *pstr_sfb_prms, + WORD32 usac_independancy_flag, WORD32 num_chans, + ia_usac_data_struct *ptr_usac_data, + ia_usac_encoder_config_struct *ptr_usac_config, WORD32 chn, + WORD32 ele_id) { + IA_ERRORCODE err_code; + WORD32 i = 0, sfb; + WORD32 j = 0; + WORD32 k; + WORD32 max_bits; + WORD32 ch; + iusace_scratch_mem *pstr_scratch = &ptr_usac_data->str_scratch; + WORD32 num_scfs[2]; + FLOAT32 **sfb_form_fac = &pstr_scratch->ptr_sfb_form_fac[0]; + WORD32 max_ch_dyn_bits[2] = {0}; + FLOAT32 ch_bit_dist[2]; + WORD32 constraints_fulfilled; + WORD32 iterations = 0; + WORD32 max_val; + WORD32 kk, idx = 0; + + FLOAT32 *ptr_exp_spec = pstr_scratch->p_exp_spec; + FLOAT32 *ptr_mdct_spec_float = pstr_scratch->p_mdct_spec_float; + ia_psy_mod_data_struct *pstr_psy_data = ptr_usac_data->str_psy_mod.str_psy_data; + ia_qc_out_data_struct *pstr_qc_out = &ptr_usac_data->str_qc_main.str_qc_out; + ia_psy_mod_out_data_struct *pstr_psy_out = ptr_usac_data->str_psy_mod.str_psy_out_data; + ia_qc_data_struct *pstr_qc_data = &ptr_usac_data->str_qc_main.str_qc_data[ele_id]; + ia_adj_thr_elem_struct *pstr_adj_thr_elem = &pstr_qc_data->str_adj_thr_ele; + WORD32 *ptr_window_sequence = pstr_sfb_prms->window_sequence; + WORD32 *ptr_max_sfb = pstr_sfb_prms->max_sfb; + WORD32 *ptr_num_sfb = pstr_sfb_prms->num_sfb; + WORD32 *ptr_num_window_groups = pstr_sfb_prms->num_window_groups; + WORD32 bitres_bits, bitres_diff; + + memset(num_scfs, 0, 2 * sizeof(num_scfs[0])); + + for (ch = chn; ch < chn + num_chans; ch++) { + num_scfs[idx] = ptr_num_sfb[ch] * ptr_num_window_groups[ch]; + + pstr_psy_out[ch].sfb_count = num_scfs[idx]; + pstr_psy_out[ch].sfb_per_group = num_scfs[idx] / ptr_num_window_groups[ch]; + pstr_psy_out[ch].window_sequence = pstr_psy_data[ch].window_sequence; + pstr_psy_out[ch].window_shape = iusace_window_shape[pstr_psy_data[ch].window_sequence]; + pstr_psy_out[ch].ptr_spec_coeffs = ptr_usac_data->spectral_line_vector[ch]; + pstr_psy_out[ch].ptr_sfb_energy = pstr_psy_data[ch].ptr_sfb_energy_long; + pstr_psy_out[ch].ptr_sfb_thr = pstr_psy_data[ch].ptr_sfb_thr_long; + pstr_psy_out[ch].ptr_sfb_spread_energy = pstr_psy_data[ch].ptr_sfb_spreaded_energy_long; + + for (j = 0; j < num_scfs[idx]; j++) { + pstr_psy_out[ch].sfb_offsets[j] = pstr_sfb_prms->grouped_sfb_offset[ch][j]; + } + pstr_psy_out[ch].sfb_offsets[num_scfs[idx]] = + pstr_sfb_prms->grouped_sfb_offset[ch][num_scfs[idx]]; + + for (j = 0; j < MAX_NUM_GROUPED_SFB; j++) { + sfb_form_fac[idx][j] = MIN_FLT_VAL; + } + + iusace_calc_form_fac_per_chan(&pstr_psy_out[ch], pstr_scratch, idx); + idx++; + } + + pstr_qc_out->static_bits = + iusace_count_static_bits(ptr_usac_data, ptr_usac_config, pstr_sfb_prms, pstr_psy_out, + num_chans, chn, usac_independancy_flag, ele_id); +#if DEBUG_DUMP + fprintf(out_file, "\nFrame: %d\n", ptr_usac_data->frame_count); + fprintf(out_file, "%d\t", pstr_qc_out->static_bits); +#endif + + iusace_adj_bitrate(pstr_qc_data, pstr_qc_data->ch_bitrate, ptr_usac_config->core_sample_rate, + ptr_usac_config->ccfl); + err_code = + iusace_adj_thr(pstr_adj_thr_elem, pstr_psy_out, ch_bit_dist, pstr_qc_out, + pstr_qc_data->avg_bits - pstr_qc_out->static_bits, pstr_qc_data->bit_res_lvl, + pstr_qc_data->max_bitres_bits, pstr_qc_out->static_bits, + &pstr_qc_data->max_bit_fac, num_chans, chn, pstr_scratch); + if (err_code != IA_NO_ERROR) { + return err_code; + } + + iusace_estimate_scfs_chan(pstr_psy_out, pstr_qc_out->str_qc_out_chan, num_chans, chn, + pstr_scratch); + idx = 0; + for (ch = 0; ch < num_chans; ch++) { + max_ch_dyn_bits[ch] = (WORD32)floor( + ch_bit_dist[ch] * (FLOAT32)(pstr_qc_data->avg_bits + pstr_qc_data->bit_res_lvl - 7 - + pstr_qc_out->static_bits)); + idx++; + } + + pstr_qc_out->dyn_bits = 0; + idx = 0; + for (ch = chn; ch < chn + num_chans; ch++) { + iterations = 0; + + for (kk = 0; kk < ptr_usac_config->ccfl; kk++) { + ptr_exp_spec[kk] = (FLOAT32)pstr_psy_out[ch].ptr_spec_coeffs[kk]; + ptr_mdct_spec_float[kk] = (FLOAT32)pstr_psy_out[ch].ptr_spec_coeffs[kk]; + } + do { + constraints_fulfilled = 1; + WORD32 quant_spec_is_zero = 1; + if (iterations > 0) { + for (WORD32 sfb_offs = 0; sfb_offs < pstr_psy_out[ch].sfb_count; + sfb_offs += pstr_psy_out[ch].sfb_per_group) { + for (sfb = 0; sfb < pstr_psy_out[ch].max_sfb_per_grp; sfb++) { + WORD32 scalefactor = pstr_qc_out->str_qc_out_chan[idx].scalefactor[sfb + sfb_offs]; + iusace_quantize_lines( + pstr_qc_out->str_qc_out_chan[idx].global_gain - scalefactor, + pstr_psy_out[ch].sfb_offsets[sfb_offs + sfb + 1] - + pstr_psy_out[ch].sfb_offsets[sfb_offs + sfb], + ptr_exp_spec + pstr_psy_out[ch].sfb_offsets[sfb_offs + sfb], + pstr_qc_out->str_qc_out_chan[idx].quant_spec + + pstr_psy_out[ch].sfb_offsets[sfb_offs + sfb], + ptr_mdct_spec_float + pstr_psy_out[ch].sfb_offsets[sfb_offs + sfb]); + } + } + } + max_val = + iusace_calc_max_val_in_sfb(pstr_psy_out[ch].sfb_count, pstr_psy_out[ch].max_sfb_per_grp, + pstr_psy_out[ch].sfb_per_group, pstr_psy_out[ch].sfb_offsets, + pstr_qc_out->str_qc_out_chan[idx].quant_spec); + if (max_val > MAX_QUANT) { + constraints_fulfilled = 0; + } + + for (k = 0; k < num_scfs[idx]; k++) { + for (i = pstr_sfb_prms->grouped_sfb_offset[ch][k]; + i < pstr_sfb_prms->grouped_sfb_offset[ch][k + 1]; i++) { + ptr_usac_data->str_quant_info[idx].quant_degroup[i] = + (WORD32)pstr_qc_out->str_qc_out_chan[idx].quant_spec[i]; + if (ptr_usac_data->str_quant_info[idx].quant_degroup[i] != 0) { + quant_spec_is_zero = 0; + } + } + } + + if (ptr_window_sequence[ch] == EIGHT_SHORT_SEQUENCE) { + iusace_degroup_int(pstr_sfb_prms->grouped_sfb_offset[ch], ptr_num_sfb[ch], + ptr_usac_data->str_scratch.p_degroup_scratch, + ptr_usac_data->str_quant_info[idx].quant_degroup, + ptr_num_window_groups[ch], pstr_sfb_prms->window_group_length[ch], + ptr_usac_config->ccfl); + } + + ptr_usac_data->str_quant_info[idx].max_spec_coeffs = 0; + for (k = 0; k < ptr_max_sfb[ch]; k++) { + ptr_usac_data->str_quant_info[idx].max_spec_coeffs += + pstr_sfb_prms->sfb_width_table[ch][k]; + } + + for (i = 0; i < num_scfs[idx]; i++) { + ptr_usac_data->str_quant_info[idx].scale_factor[i] = + pstr_qc_out->str_qc_out_chan[idx].global_gain - + pstr_qc_out->str_qc_out_chan[idx].scalefactor[i] + SF_OFFSET; + } + + max_bits = iusace_count_fd_bits(pstr_sfb_prms, ptr_usac_data, usac_independancy_flag, + ptr_usac_config, ch, idx); + + if (max_bits > max_ch_dyn_bits[idx]) { + constraints_fulfilled = 0; + } + if (!constraints_fulfilled) { + pstr_qc_out->str_qc_out_chan[idx].global_gain++; + } + if (quant_spec_is_zero == 1) { + constraints_fulfilled = 1; + if (iterations > 0) { + max_bits = max_ch_dyn_bits[idx]; + } + } + iterations++; + } while (!constraints_fulfilled); + + pstr_qc_out->dyn_bits += max_bits; + + if (ptr_usac_data->noise_filling[ele_id]) { + WORD32 max_nf_sfb = ptr_max_sfb[ch]; + + if (ptr_window_sequence[ch] != EIGHT_SHORT_SEQUENCE) { + iusace_noise_filling( + &ptr_usac_data->noise_level[idx], &ptr_usac_data->noise_offset[idx], + ptr_usac_data->spectral_line_vector[ch], &ptr_usac_data->str_quant_info[idx], + pstr_sfb_prms->grouped_sfb_offset[ch], max_nf_sfb, ptr_usac_config->ccfl, + ptr_num_window_groups[ch], pstr_sfb_prms->window_group_length[ch], 160, + ptr_usac_data->str_scratch.p_noise_filling_highest_tone); + } else { + iusace_noise_filling( + &ptr_usac_data->noise_level[idx], &ptr_usac_data->noise_offset[idx], + ptr_usac_data->spectral_line_vector[ch], &ptr_usac_data->str_quant_info[idx], + pstr_sfb_prms->grouped_sfb_offset[ch], max_nf_sfb, ptr_usac_config->ccfl >> 3, + ptr_num_window_groups[ch], pstr_sfb_prms->window_group_length[ch], 20, + (FLOAT64 *)ptr_usac_data->str_scratch.p_noise_filling_highest_tone); + } + + if (ptr_usac_data->noise_level[idx] == 0 && ptr_usac_data->noise_offset[idx] != 0 && + pstr_sfb_prms->common_win[ch]) { + ptr_usac_data->complex_coef[ch] = 0; + } + } + idx++; + } + + pstr_adj_thr_elem->dyn_bits_last = pstr_qc_out->dyn_bits; + + bitres_bits = pstr_qc_data->max_bitres_bits - pstr_qc_data->bit_res_lvl; + bitres_diff = pstr_qc_data->avg_bits - (pstr_qc_out->static_bits + pstr_qc_out->dyn_bits); + pstr_qc_out->fill_bits = MAX(0, (bitres_diff - bitres_bits)); + + if (pstr_qc_data->avg_bits > 0) { + pstr_qc_data->bit_res_lvl += + pstr_qc_data->avg_bits - + (pstr_qc_out->static_bits + pstr_qc_out->dyn_bits + pstr_qc_out->fill_bits); + } else { + pstr_qc_data->bit_res_lvl = pstr_qc_data->max_bits; + } + + if (pstr_qc_data->bit_res_lvl < 0 || + pstr_qc_data->bit_res_lvl > pstr_qc_data->max_bitres_bits) { + return IA_EXHEAACE_EXE_FATAL_USAC_INVALID_BIT_RSVR_LVL; + } + + return IA_NO_ERROR; +} diff --git a/encoder/ixheaace_hybrid.c b/encoder/ixheaace_hybrid.c index 28384ad..86b74a2 100644 --- a/encoder/ixheaace_hybrid.c +++ b/encoder/ixheaace_hybrid.c @@ -331,15 +331,15 @@ VOID ixheaace_hybrid_synthesis(const FLOAT32 **ptr_hybrid_real_flt, FLOAT32 **ptr_qmf_imag_flt, const WORD32 *ptr_hyb_res) { WORD32 k, n, band; ixheaace_hybrid_res hybrid_res; - WORD32 chOffset = 0; + WORD32 ch_offset = 0; FLOAT32 temp1, temp2; FLOAT32 *ptr_qmf_real; FLOAT32 *ptr_qmf_imag; for (band = 0; band < IXHEAACE_NUM_QMF_BANDS_IN_HYBRID; band++) { - const FLOAT32 *ptr_hybrid_real = &ptr_hybrid_real_flt[0][chOffset]; - const FLOAT32 *ptr_hybrid_imag = &ptr_hybrid_imag_flt[0][chOffset]; + const FLOAT32 *ptr_hybrid_real = &ptr_hybrid_real_flt[0][ch_offset]; + const FLOAT32 *ptr_hybrid_imag = &ptr_hybrid_imag_flt[0][ch_offset]; hybrid_res = (ixheaace_hybrid_res)ptr_hyb_res[band]; @@ -365,6 +365,6 @@ VOID ixheaace_hybrid_synthesis(const FLOAT32 **ptr_hybrid_real_flt, *ptr_qmf_imag = temo_imag; ptr_qmf_imag += IXHEAACE_QMF_CHANNELS; } - chOffset += hybrid_res; + ch_offset += hybrid_res; } } diff --git a/encoder/ixheaace_memory_standards.h b/encoder/ixheaace_memory_standards.h index 765825a..b4ce274 100644 --- a/encoder/ixheaace_memory_standards.h +++ b/encoder/ixheaace_memory_standards.h @@ -19,6 +19,7 @@ */ #pragma once + /*****************************************************************************/ /* Constant hash defines */ /*****************************************************************************/ diff --git a/encoder/ixheaace_mps_bitstream.c b/encoder/ixheaace_mps_bitstream.c index 66d37a6..069c5da 100644 --- a/encoder/ixheaace_mps_bitstream.c +++ b/encoder/ixheaace_mps_bitstream.c @@ -21,6 +21,10 @@ #include #include #include "ixheaac_type_def.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" #include "ixheaace_api.h" #include "ixheaac_error_standards.h" #include "ixheaace_error_codes.h" diff --git a/encoder/ixheaace_mps_dct.c b/encoder/ixheaace_mps_dct.c index 40f98f5..e296fb9 100644 --- a/encoder/ixheaace_mps_dct.c +++ b/encoder/ixheaace_mps_dct.c @@ -102,7 +102,7 @@ IA_ERRORCODE ixheaace_mps_212_dct_iv(FLOAT32 *ptr_data, WORD32 length, WORD8 *pt accu_2 = ptr_data_1[1]; ptr_data_1[1] = -ptr_data_0[1]; - for (step = sin_step, idx = 1; idx<(length_by_2 + 1)>> 1; idx++, step += sin_step) { + for (step = sin_step, idx = 1; idx < (length_by_2 + 1) >> 1; idx++, step += sin_step) { ixheaace_cmplx_str twd = ptr_cmplx_sin_twiddle[step]; accu_3 = (accu_1 * twd.re) - (accu_2 * twd.im); accu_4 = (accu_1 * twd.im) + (accu_2 * twd.re); @@ -182,7 +182,7 @@ IA_ERRORCODE ixheaace_mps_212_dst_iv(FLOAT32 *ptr_data, WORD32 length, WORD8 *pt ptr_data_1[1] = -ptr_data_0[0]; ptr_data_0[0] = ptr_data_0[1]; - for (step = sin_step, idx = 1; idx<(length_by_2 + 1)>> 1; idx++, step += sin_step) { + for (step = sin_step, idx = 1; idx < (length_by_2 + 1) >> 1; idx++, step += sin_step) { ixheaace_cmplx_str twd = ptr_cmplx_sin_twiddle[step]; accu_3 = (accu_1 * twd.re) - (accu_2 * twd.im); diff --git a/encoder/ixheaace_mps_enc.c b/encoder/ixheaace_mps_enc.c index a4cd474..25ff8a5 100644 --- a/encoder/ixheaace_mps_enc.c +++ b/encoder/ixheaace_mps_enc.c @@ -22,6 +22,10 @@ #include #include #include "ixheaac_type_def.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" #include "ixheaace_api.h" #include "ixheaac_error_standards.h" #include "ixheaace_error_codes.h" @@ -861,7 +865,7 @@ static WORD32 ixheaace_mps_212_write_spatial_specific_config_data( ixheaace_mps_space_info pstr_space_encoder_info; ixheaace_mps_212_get_info(pstr_mps_enc->ptr_sac_encoder, &pstr_space_encoder_info); - for (idx = 0; idxnum_ssc_size_bits>> 3; idx++) { + for (idx = 0; idx < pstr_space_encoder_info.p_ssc_buf->num_ssc_size_bits >> 3; idx++) { ixheaace_write_bits(pstr_bit_buf, pstr_space_encoder_info.p_ssc_buf->ptr_ssc[idx], 8); written_bits += 8; } @@ -907,6 +911,7 @@ IA_ERRORCODE ixheaace_mps_212_initialise(VOID *pstr_handle_mps, const WORD32 aud } break; case 2: + case 4: if (!((sampling_rate >= fs_low) && (sampling_rate < fs_high))) { return IA_EXHEAACE_INIT_FATAL_MPS_INIT_FAILED; } diff --git a/encoder/ixheaace_mps_frame_windowing.c b/encoder/ixheaace_mps_frame_windowing.c index aa09901..87ddb38 100644 --- a/encoder/ixheaace_mps_frame_windowing.c +++ b/encoder/ixheaace_mps_frame_windowing.c @@ -86,7 +86,7 @@ ixheaace_mps_212_frame_window_init( pstr_frame_win->start_rect = time_slots >> 1; pstr_frame_win->stop_slope = ((3 * time_slots) >> 1) - 1; pstr_frame_win->stop_rect = time_slots; - for (slot = 0; slot> 1; slot++) { + for (slot = 0; slot < time_slots >> 1; slot++) { pstr_frame_win->p_tapper_sync_flt[slot] = (FLOAT32)slot / time_slots; } pstr_frame_win->p_tapper_sync_flt[time_slots >> 1] = 1.0f; diff --git a/encoder/ixheaace_mps_nlc_enc.c b/encoder/ixheaace_mps_nlc_enc.c index 4f5dae7..c56bc30 100644 --- a/encoder/ixheaace_mps_nlc_enc.c +++ b/encoder/ixheaace_mps_nlc_enc.c @@ -170,11 +170,9 @@ static VOID ixheaace_mps_212_apply_pcm_coding(ixheaace_bit_buf_handle pstr_bit_b grp_val = 0; for (lvl = 0; lvl < grp_len; lvl++) { idx = val + lvl; - next_val = (in_data_2 == NULL) - ? in_data_1[idx] - : (in_data_1 == NULL) - ? in_data_2[idx] - : ((idx & 01) ? in_data_2[idx >> 1] : in_data_1[idx >> 1]); + next_val = (in_data_2 == NULL) ? in_data_1[idx] + : (in_data_1 == NULL) ? in_data_2[idx] + : ((idx & 01) ? in_data_2[idx >> 1] : in_data_1[idx >> 1]); grp_val = grp_val * n_levels + next_val + offset; } ixheaace_write_bits(pstr_bit_buf, grp_val, pcm_block_size[grp_len]); @@ -858,11 +856,9 @@ static VOID ixheaace_mps_515_apply_pcm_coding(ixheaace_bit_buf_handle pstr_bit_b grp_val = 0; for (j = 0; j < grp_len; j++) { idx = i + j; - next_val = (in_data_2 == NULL) - ? in_data_1[idx] - : (in_data_1 == NULL) - ? in_data_2[idx] - : ((idx & 01) ? in_data_2[idx >> 1] : in_data_1[idx >> 1]); + next_val = (in_data_2 == NULL) ? in_data_1[idx] + : (in_data_1 == NULL) ? in_data_2[idx] + : ((idx & 01) ? in_data_2[idx >> 1] : in_data_1[idx >> 1]); grp_val = grp_val * n_levels + next_val + offset; } diff --git a/encoder/ixheaace_mps_param_extract.c b/encoder/ixheaace_mps_param_extract.c index f919988..07a3737 100644 --- a/encoder/ixheaace_mps_param_extract.c +++ b/encoder/ixheaace_mps_param_extract.c @@ -21,6 +21,10 @@ #include #include #include "ixheaac_type_def.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" #include "ixheaace_api.h" #include "ixheaac_error_standards.h" #include "ixheaace_error_codes.h" diff --git a/encoder/ixheaace_mps_tools_rom.c b/encoder/ixheaace_mps_tools_rom.c index a415fbd..f39bf5c 100644 --- a/encoder/ixheaace_mps_tools_rom.c +++ b/encoder/ixheaace_mps_tools_rom.c @@ -21,6 +21,10 @@ #include #include "ixheaac_type_def.h" #include "ixheaace_error_codes.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" #include "ixheaace_api.h" #include "ixheaace_mps_common_fix.h" #include "ixheaace_mps_defines.h" diff --git a/encoder/ixheaace_nf.c b/encoder/ixheaace_nf.c new file mode 100644 index 0000000..00e67a1 --- /dev/null +++ b/encoder/ixheaace_nf.c @@ -0,0 +1,165 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include +#include "iusace_cnst.h" +#include "iusace_type_def.h" +#include "ixheaac_constants.h" +#include "iusace_bitbuffer.h" +#include "iusace_tns_usac.h" +#include "iusace_fd_quant.h" +#include "ixheaac_basic_ops32.h" +#include "ixheaac_basic_ops40.h" +#include "ixheaac_basic_ops.h" +#include "ixheaace_nf.h" + +static VOID iusace_noise_filling_limiter(FLOAT64 *energy, FLOAT64 *ptr_spec, + WORD32 *ptr_quant_spec, WORD32 n0_by_4, + WORD32 *ptr_sfb_offset, WORD32 sb, WORD32 cntr, + FLOAT64 *ptr_highest_tone) { + WORD32 n, i; + FLOAT64 tone_energy; + + if (!n0_by_4) return; + if (cntr <= n0_by_4) return; + + memset(ptr_highest_tone, 0, n0_by_4 * sizeof(*ptr_highest_tone)); + + /* finds the n0_by_4 strongest bins */ + for (i = ptr_sfb_offset[sb]; i < ptr_sfb_offset[sb + 1]; i++) { + if (!ptr_quant_spec[i]) { + tone_energy = ptr_spec[i] * ptr_spec[i]; + + for (n = 0; n < n0_by_4; n++) { + if (tone_energy > ptr_highest_tone[n]) { + memmove(ptr_highest_tone + 1 + n, ptr_highest_tone + n, + (n0_by_4 - n - 1) * sizeof(*ptr_highest_tone)); + ptr_highest_tone[n] = tone_energy; + break; + } + } + } + } + /* remove the contribution of the highest_tone components */ + for (n = 0; n < n0_by_4; n++) *energy -= ptr_highest_tone[n]; + + /* add the average component energy */ + *energy += n0_by_4 * (*energy) / (cntr - n0_by_4); + return; +} + +VOID iusace_noise_filling(WORD32 *noise_level, WORD32 *noise_offset, FLOAT64 *ptr_quant_spec, + ia_usac_quant_info_struct *pstr_quant_info, WORD32 *ptr_sfb_offset, + WORD32 max_sfb, WORD32 window_size_samples, WORD32 num_window_groups, + const WORD32 *ptr_window_group_length, + WORD32 noise_filling_start_offset, FLOAT64 *ptr_scratch_buf) { + FLOAT64 energy; + FLOAT64 noise_level_temp; + FLOAT64 noise_offset_temp; + + FLOAT64 sum_sfb_on, sum_sfb_off; + FLOAT64 e_sfb_on, e_sfb_off; + + WORD32 n0; + WORD32 start_sfb, sfb, i; + WORD32 band_quantized_to_zero; + + FLOAT64 alpha = 0.15; /* prudence factor */ + WORD32 grp = 0; + + e_sfb_on = 1e-6; + e_sfb_off = 1e-6; + + sum_sfb_on = 1e-6; + sum_sfb_off = 1e-6; + + *noise_offset = 0; + *noise_level = 0; + + for (sfb = 0; sfb < max_sfb; sfb++) { + if (ptr_sfb_offset[sfb + 1] > noise_filling_start_offset) break; + } + start_sfb = sfb; + for (grp = 0; grp < num_window_groups; grp++) { + WORD32 grp_win = 0; + for (sfb = start_sfb; sfb < max_sfb; sfb++) { + band_quantized_to_zero = 1; + for (grp_win = 0; grp_win < ptr_window_group_length[grp]; grp_win++) { + WORD32 offset = grp_win * window_size_samples; + energy = 0; + n0 = 0; + for (i = ptr_sfb_offset[sfb]; i < ptr_sfb_offset[sfb + 1]; i++) { + /* calculate energy if the quantized value is non zero */ + if (!pstr_quant_info->quant_degroup[offset + i]) { + energy += ptr_quant_spec[offset + i] * ptr_quant_spec[offset + i]; + n0++; + } else { + /* All quantized values are not zero */ + band_quantized_to_zero = 0; + } + } + + /* Remove highest (tonal) contributions */ + iusace_noise_filling_limiter(&energy, &ptr_quant_spec[offset], + pstr_quant_info->quant_degroup, n0 / 4, ptr_sfb_offset, sfb, + n0, ptr_scratch_buf); + + if (band_quantized_to_zero == 0) { + e_sfb_on += energy; + sum_sfb_on += pow(2., 0.5 * pstr_quant_info->scale_factor[sfb] - 50) * n0; + } else + /* subband is completely zeroed */ + { + e_sfb_off += energy; + sum_sfb_off += pow(2., 0.5 * pstr_quant_info->scale_factor[sfb] - 58) * + (ptr_sfb_offset[sfb + 1] - ptr_sfb_offset[sfb]); + } + } + } + } + + if (num_window_groups > 1) alpha = alpha * 0.15; + + if (sum_sfb_on) { + noise_level_temp = 1.5 * (log(alpha * e_sfb_on) - log(sum_sfb_on)) / log(2.0) + 14.0; + + /* quantize to nearest integer */ + *noise_level = (WORD32)(noise_level_temp + 0.5); + + /* noise level limited to quantization range [0,7] */ + *noise_level = MAX(*noise_level, 0); + *noise_level = MIN(*noise_level, 7); + + if (*noise_level != 0) { + noise_offset_temp = + 2. * log(alpha * e_sfb_off * sum_sfb_on / sum_sfb_off / e_sfb_on) / log(2.); + + /* quantize to nearest integer */ + *noise_offset = (WORD32)(noise_offset_temp + 0.5); + + /* noise offset limited to quantization range [0,31] */ + *noise_level = *noise_offset <= 0 ? 0 : *noise_level; + *noise_offset = MIN(*noise_offset, 31); + *noise_offset = MAX(*noise_offset, 0); + } + } + return; +} diff --git a/encoder/ixheaace_nf.h b/encoder/ixheaace_nf.h new file mode 100644 index 0000000..a2d9f0d --- /dev/null +++ b/encoder/ixheaace_nf.h @@ -0,0 +1,26 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +VOID iusace_noise_filling(WORD32 *noise_level, WORD32 *noise_offset, FLOAT64 *spectrum, + ia_usac_quant_info_struct *pstr_quant_info, WORD32 *sfb_offset, + WORD32 max_sfb, WORD32 window_size_samples, WORD32 num_window_groups, + const WORD32 *window_group_length, WORD32 noise_filling_start_offset, + FLOAT64 *ptr_scratch_buf); diff --git a/encoder/ixheaace_psy_configuration.c b/encoder/ixheaace_psy_configuration.c index f18f3d0..e1fc2c9 100644 --- a/encoder/ixheaace_psy_configuration.c +++ b/encoder/ixheaace_psy_configuration.c @@ -23,6 +23,10 @@ #include "ixheaac_type_def.h" #include "ixheaac_constants.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" #include "ixheaace_api.h" #include "ixheaace_aac_constants.h" #include "ixheaac_basic_ops32.h" diff --git a/encoder/ixheaace_psy_mod.c b/encoder/ixheaace_psy_mod.c index 0f234d6..013c1db 100644 --- a/encoder/ixheaace_psy_mod.c +++ b/encoder/ixheaace_psy_mod.c @@ -25,6 +25,10 @@ #include "ixheaac_type_def.h" #include "ixheaac_constants.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" #include "ixheaace_api.h" #include "ixheaace_aac_constants.h" #include "ixheaac_error_standards.h" diff --git a/encoder/ixheaace_qc_util.c b/encoder/ixheaace_qc_util.c index 0541700..ec69a1d 100644 --- a/encoder/ixheaace_qc_util.c +++ b/encoder/ixheaace_qc_util.c @@ -22,6 +22,10 @@ #include "ixheaac_type_def.h" #include "ixheaac_constants.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" #include "ixheaace_api.h" #include "ixheaace_aac_constants.h" #include "ixheaace_error_codes.h" @@ -431,7 +435,6 @@ IA_ERRORCODE ia_enhaacplus_enc_finalize_bit_consumption(ixheaace_qc_state *pstr_ if ((pstr_qc_out->tot_dyn_bits_used + pstr_qc_out->tot_static_bits_used + pstr_qc_out->tot_anc_bits_used + pstr_qc_out->total_fill_bits + pstr_qc_out->align_bits) > pstr_qc_kernel->max_bits_tot) { - // return -1; } return IA_NO_ERROR; diff --git a/encoder/ixheaace_quant.c b/encoder/ixheaace_quant.c index 19a327b..230d94f 100644 --- a/encoder/ixheaace_quant.c +++ b/encoder/ixheaace_quant.c @@ -38,7 +38,7 @@ VOID iaace_quantize_lines(const WORD32 gain, const WORD32 num_lines, FLOAT32 *pt WORD32 line; quantizer = ixheaace_fd_quant_table[gain + 128]; - ; + for (line = 0; line < num_lines; line++) { FLOAT32 tmp = ptr_mdct_spec[line]; if (tmp < 0.0f) { diff --git a/encoder/ixheaace_resampler.h b/encoder/ixheaace_resampler.h index d8aa80b..cfc3b4d 100644 --- a/encoder/ixheaace_resampler.h +++ b/encoder/ixheaace_resampler.h @@ -121,3 +121,7 @@ WORD32 ia_enhaacplus_enc_compute_resampling_ratio(WORD32 ccfl_idx); VOID ixheaace_upsampling_inp_buf_generation(FLOAT32 *ptr_inp_buf, FLOAT32 *ptr_temp_buf, WORD32 num_samples, WORD32 upsamp_fac, WORD32 offset); + +IA_ERRORCODE +ia_enhaacplus_enc_init_iir_sos_resampler(ixheaace_iir_sos_resampler *pstr_resampler, WORD32 ratio, + ixheaace_resampler_sos_table *pstr_resampler_table); \ No newline at end of file diff --git a/encoder/ixheaace_resampler_init.c b/encoder/ixheaace_resampler_init.c index eea1430..c5ab30f 100644 --- a/encoder/ixheaace_resampler_init.c +++ b/encoder/ixheaace_resampler_init.c @@ -55,3 +55,32 @@ IA_ERRORCODE ia_enhaacplus_enc_init_iir_resampler(ixheaace_iir21_resampler *pstr return error; } +IA_ERRORCODE +ia_enhaacplus_enc_init_iir_sos_resampler(ixheaace_iir_sos_resampler *pstr_resampler, WORD32 ratio, + ixheaace_resampler_sos_table *pstr_resampler_table) + +{ + struct ixheaace_iir_params_sos const *current_set = NULL; + IA_ERRORCODE error = IA_NO_ERROR; + + if (pstr_resampler == NULL) { + error = IA_EXHEAACE_INIT_FATAL_USAC_RESAMPLER_INIT_FAILED; + return error; + } + + memset(pstr_resampler->iir_filter.ring_buf_sos_1, 0, + (LEN_RING_BUF_SOS_1 * sizeof(pstr_resampler->iir_filter.ring_buf_sos_1[0]))); + memset(pstr_resampler->iir_filter.ring_buf_sos_2, 0, + (LEN_RING_BUF_SOS_2 * sizeof(pstr_resampler->iir_filter.ring_buf_sos_2[0]))); + + current_set = &(pstr_resampler_table->iir_param_set_sos); + + pstr_resampler->iir_filter.ptr_coeff_iir_den = ¤t_set->coeff_iir_sos_den[0][0]; + pstr_resampler->iir_filter.ptr_coeff_iir_num = ¤t_set->coeff_iir_sos_num[0][0]; + pstr_resampler->ratio = ratio; + pstr_resampler->pending = ratio - 1; + pstr_resampler->iir_filter.gain_sos = current_set->gain_sos; + pstr_resampler->delay = current_set->delay; + + return error; +} \ No newline at end of file diff --git a/encoder/ixheaace_sbr.h b/encoder/ixheaace_sbr.h index e246ceb..a7205b9 100644 --- a/encoder/ixheaace_sbr.h +++ b/encoder/ixheaace_sbr.h @@ -57,6 +57,7 @@ struct ixheaace_str_sbr_env_data { ixheaace_freq_res freq_res_fix; ixheaace_invf_mode sbr_invf_mode; ixheaace_invf_mode sbr_invf_mode_vec[MAXIMUM_NUM_NOISE_VALUES]; + ixheaace_pvc_bs_info pvc_info; ixheaace_sbr_xpos_mode sbr_xpos_mode; WORD32 ienvelope[IXHEAACE_MAX_ENV][MAXIMUM_FREQ_COEFFS]; WORD32 code_book_scf_lav_balance; @@ -128,6 +129,8 @@ struct ixheaace_str_enc_channel { ixheaace_str_sbr_qmf_filter_bank str_sbr_qmf; ixheaace_str_sbr_env_frame str_sbr_env_frame; ixheaace_str_sbr_ton_corr_est str_ton_corr; + ixheaace_str_inter_tes_params str_inter_tes_enc; + ixheaace_str_hbe_enc *pstr_hbe_enc; WORD32 sbr_amp_res_init; struct ixheaace_str_sbr_env_data enc_env_data; }; diff --git a/encoder/ixheaace_sbr_code_envelope.c b/encoder/ixheaace_sbr_code_envelope.c index 6e33515..827ce00 100644 --- a/encoder/ixheaace_sbr_code_envelope.c +++ b/encoder/ixheaace_sbr_code_envelope.c @@ -47,6 +47,8 @@ #include "ixheaace_sbr_noise_floor_est.h" #include "ixheaace_sbr_ton_corr.h" +#include "iusace_esbr_pvc.h" +#include "iusace_esbr_inter_tes.h" #include "ixheaace_sbr.h" #include "ixheaace_common_utils.h" @@ -108,7 +110,7 @@ ixheaace_init_sbr_huffman_tabs(ixheaace_pstr_sbr_env_data pstr_sbr_env, break; default: - return IA_EXHAACE_EXE_FATAL_SBR_INVALID_AMP_RES; + return IA_EXHEAACE_EXE_FATAL_SBR_INVALID_AMP_RES; break; } diff --git a/encoder/ixheaace_sbr_code_envelope_lp.c b/encoder/ixheaace_sbr_code_envelope_lp.c index 24ff21b..c452715 100644 --- a/encoder/ixheaace_sbr_code_envelope_lp.c +++ b/encoder/ixheaace_sbr_code_envelope_lp.c @@ -47,6 +47,8 @@ #include "ixheaace_sbr_noise_floor_est.h" #include "ixheaace_sbr_ton_corr.h" +#include "iusace_esbr_pvc.h" +#include "iusace_esbr_inter_tes.h" #include "ixheaace_sbr.h" #include "ixheaace_common_utils.h" @@ -171,7 +173,8 @@ IA_ERRORCODE ixheaace_code_envelope(WORD32 *ptr_sfb_energy, const ixheaace_freq_ WORD32 index; WORD32 delta_lcl_bits = 0; - if (ptr_energy[band - 1] - ptr_energy[band] > code_book_scf_lav_lvl_freq) { + if (ixheaac_sub32_sat(ptr_energy[band - 1], ptr_energy[band]) > + code_book_scf_lav_lvl_freq) { ptr_energy[band] = ptr_energy[band - 1] - code_book_scf_lav_lvl_freq; } @@ -195,8 +198,7 @@ IA_ERRORCODE ixheaace_code_envelope(WORD32 *ptr_sfb_energy, const ixheaace_freq_ ixheaace_map_low_res_energy_value(current_energy, pstr_code_env->sfb_nrg_prev, offset, band, freq_res[i]); - if ((delta_t[band] > 31) || (delta_t[band] < -31)) // new tmp_var fix - { + if ((delta_t[band] > 31) || (delta_t[band] < -31)) { delta_t[band] = 31; } diff --git a/encoder/ixheaace_sbr_enc_struct.h b/encoder/ixheaace_sbr_enc_struct.h index 4f7d9c4..9b0235c 100644 --- a/encoder/ixheaace_sbr_enc_struct.h +++ b/encoder/ixheaace_sbr_enc_struct.h @@ -27,8 +27,20 @@ #define ALIGNMENT_DEFINE __attribute__((aligned(8))) -#define IXHEAACE_SBR_SCR_SIZE_PVC (0) -#define IXHEAACE_SBR_SCR_SIZE_TES (0) +#ifndef max +#define max(a, b) (a > b ? a : b) +#endif + +// 4 is for sizeof FLOAT32 data type +#define IXHEAACE_SBR_SCR_SIZE_PVC \ + (((IXHEAACE_ESBR_PVC_NUM_TS * IXHEAACE_ESBR_PVC_NUM_QMF_BANDS_CORE + \ + IXHEAACE_ESBR_PVC_NUM_TS * IXHEAACE_ESBR_PVC_NUM_QMF_BANDS) * \ + 4) + \ + 128) + +// 4 is for sizeof FLOAT32 data type and 2 is for two-channels +#define IXHEAACE_SBR_SCR_SIZE_TES \ + ((IXHEAACE_TIMESLOT_BUFFER_SIZE * IXHEAACE_QMF_CHANNELS * 2 * 4) + 128) #define IXHEAACE_SBR_SCR_SIZE \ MAX(IXHEAACE_SBR_SCR_SIZE_PVC, MAX(IXHEAACE_SBR_SCR_SIZE_TES, (2 * 1024))) @@ -60,4 +72,6 @@ struct ixheaace_str_sbr_enc { WORD32 *ptr_common_buffer1; WORD32 *ptr_common_buffer2; ixheaace_str_sbr_enc_scratch *ptr_sbr_enc_scr; + ixheaace_pvc_enc *pstr_pvc_enc; + FLOAT32 *ptr_hbe_resample_buf; }; diff --git a/encoder/ixheaace_sbr_env_est.c b/encoder/ixheaace_sbr_env_est.c index 3dc7e1f..426aa75 100644 --- a/encoder/ixheaace_sbr_env_est.c +++ b/encoder/ixheaace_sbr_env_est.c @@ -51,6 +51,8 @@ #include "ixheaace_common_rom.h" #include "ixheaace_sbr_ton_corr.h" +#include "iusace_esbr_pvc.h" +#include "iusace_esbr_inter_tes.h" #include "ixheaace_sbr.h" #include "ixheaace_bitbuffer.h" @@ -80,12 +82,14 @@ #include "ixheaace_rom.h" #include "ixheaace_common_rom.h" #include "ixheaace_bitbuffer.h" + #include "ixheaace_sbr_main.h" #include "ixheaace_common_rom.h" #include "ixheaace_sbr_missing_harmonics_det.h" #include "ixheaace_sbr_inv_filtering_estimation.h" #include "ixheaace_sbr_noise_floor_est.h" #include "ixheaace_sbr_ton_corr.h" +#include "iusace_esbr_pvc.h" #include "ixheaace_sbr.h" #include "ixheaace_sbr_freq_scaling.h" @@ -188,7 +192,7 @@ static IA_ERRORCODE ixheaace_calculate_sbr_envelope( WORD32 missing_harmonic = 0; if ((ca != 1) && (ca != 2)) { - return IA_EXHAACE_EXE_FATAL_SBR_INVALID_AMP_RES; + return IA_EXHEAACE_EXE_FATAL_SBR_INVALID_AMP_RES; } if (stereo_mode == SBR_COUPLING) { @@ -315,8 +319,7 @@ static IA_ERRORCODE ixheaace_calculate_sbr_envelope( energy_left = (energy_left + energy_right) * 0.5f; energy_right = (tmp_ene_l + 1) / (energy_right + 1); } - } /* end missing_harmonic */ - else { + } else { count = (stop_pos - start_pos) * (ui - li); k = li; @@ -364,15 +367,16 @@ static IA_ERRORCODE ixheaace_calculate_sbr_envelope( } } m++; - } /*end j*/ + } if (pstr_sbr_cfg->use_parametric_coding) { m -= num_bands; for (j = 0; j < num_bands; j++) { if (freq_res == FREQ_RES_HIGH && pstr_sbr->str_sbr_extract_env.envelope_compensation[j]) { - ptr_sfb_ene_l[m] -= (WORD32)( - ca * ixheaac_abs32(pstr_sbr->str_sbr_extract_env.envelope_compensation[j])); + ptr_sfb_ene_l[m] -= + (WORD32)(ca * + ixheaac_abs32(pstr_sbr->str_sbr_extract_env.envelope_compensation[j])); } if (ptr_sfb_ene_l[m] < 0) { @@ -382,11 +386,45 @@ static IA_ERRORCODE ixheaace_calculate_sbr_envelope( } } i++; - - } /*end i*/ + } return IA_NO_ERROR; } +static WORD32 ixheaace_get_pitch_bin_deint(FLOAT32 *ptr_fft_data_real, FLOAT32 *ptr_fft_data_im, + const WORD32 *ptr_sfb_tab, WORD32 is_4_1) { + WORD32 i, j = 0, k = 0; + WORD32 bin = -1; + FLOAT32 tmp, prev_val = 0.0f; + while (ptr_sfb_tab[j] != -1) { + WORD32 size = ptr_sfb_tab[j]; + tmp = 0; + + for (i = 0; i < size; i++) { + tmp += ptr_fft_data_real[k / 2] * ptr_fft_data_real[k / 2]; + tmp += ptr_fft_data_im[k / 2] * ptr_fft_data_im[k / 2]; + k += 2; + } + + tmp = (FLOAT32)log(max(MIN_FLT_VAL, (tmp / (FLOAT32)size))); + if (j != 0) { + if (fabs(tmp - prev_val) >= 3.0f) { + if (1 == is_4_1) { + bin = ((k - (ptr_sfb_tab[j] * 2)) * 3) / 8; + } else { + bin = ((k - (ptr_sfb_tab[j] * 2)) * 3) / 4; + } + if (bin > 127) { + bin = -1; + } + break; + } + } + prev_val = tmp; + j++; + } + + return bin; +} static WORD32 ixheaace_get_pitch_bin(FLOAT32 *fft_data, const WORD32 *ptr_sfb_tab, WORD32 is_4_1) { WORD32 i, j = 0, k = 0; @@ -423,7 +461,105 @@ static WORD32 ixheaace_get_pitch_bin(FLOAT32 *fft_data, const WORD32 *ptr_sfb_ta return bin; } +static IA_ERRORCODE ixheaace_hbe_get_pitch_bins(FLOAT32 *ptr_time_in, + ixheaace_pstr_sbr_config_data pstr_sbr_cfg, + FLOAT32 *ptr_esbr_scr, + ixheaace_str_sbr_tabs *ptr_sbr_tab, + WORD32 time_sn_stride, WORD32 num_samples, + WORD32 *bin1, WORD32 *bin2) { + const WORD32 *ptr_sbr_table = NULL; + FLOAT32 *ptr_esbr_inp = ptr_esbr_scr; + ptr_esbr_scr += num_samples * 2; + FLOAT32 *ptr_esbr_inp_i = ptr_esbr_inp + num_samples; + FLOAT32 *ptr_scratch_fft = ptr_esbr_scr; + WORD32 idx, sf, is_4_1 = 0; + sf = pstr_sbr_cfg->sample_freq; + if (IXHEAACE_MAX_NUM_SAMPLES == num_samples) { + sf = sf >> 1; + is_4_1 = 1; + } + + switch (sf) { + case 16000: + ptr_sbr_table = ptr_sbr_tab->ptr_esbr_sfb_tab->sfb_bins_8k; + break; + case 22050: + ptr_sbr_table = ptr_sbr_tab->ptr_esbr_sfb_tab->sfb_bins_11k; + break; + case 24000: + ptr_sbr_table = ptr_sbr_tab->ptr_esbr_sfb_tab->sfb_bins_12k; + break; + case 32000: + ptr_sbr_table = ptr_sbr_tab->ptr_esbr_sfb_tab->sfb_bins_16k; + break; + case 44100: + ptr_sbr_table = ptr_sbr_tab->ptr_esbr_sfb_tab->sfb_bins_22k; + break; + case 48000: + ptr_sbr_table = ptr_sbr_tab->ptr_esbr_sfb_tab->sfb_bins_24k; + break; + default: + return IA_EXHEAACE_EXE_FATAL_SBR_INVALID_SAMP_FREQ; + } + if (1 == pstr_sbr_cfg->num_ch) { + if (num_samples == 2048) { + for (idx = 0; idx < num_samples; idx += 2) { + ptr_esbr_inp[idx] = ptr_time_in[time_sn_stride * idx]; + ptr_esbr_inp[idx + 1] = 0; + ptr_esbr_inp[num_samples + idx] = ptr_time_in[time_sn_stride * (idx + 1)]; + ptr_esbr_inp[num_samples + idx + 1] = 0; + } + iusace_complex_fft_2048(ptr_esbr_inp, ptr_scratch_fft); + *bin1 = ixheaace_get_pitch_bin(ptr_esbr_inp, ptr_sbr_table, is_4_1); + } else if (num_samples == IXHEAACE_MAX_NUM_SAMPLES) { + memset(ptr_esbr_inp_i, 0, num_samples * sizeof(ptr_esbr_inp_i[0])); + for (idx = 0; idx < num_samples; idx += 2) { + ptr_esbr_inp[idx / 2] = ptr_time_in[time_sn_stride * idx]; + ptr_esbr_inp[(num_samples + idx) / 2] = ptr_time_in[time_sn_stride * (idx + 1)]; + } + iusace_complex_fft_4096(ptr_esbr_inp, ptr_esbr_inp_i, ptr_scratch_fft); + *bin1 = ixheaace_get_pitch_bin_deint(ptr_esbr_inp, ptr_esbr_inp_i, ptr_sbr_table, is_4_1); + } + } else { + if (num_samples == 2048) { + for (idx = 0; idx < num_samples; idx += 2) { + ptr_esbr_inp[idx] = ptr_time_in[2 * idx]; + ptr_esbr_inp[idx + 1] = 0; + ptr_esbr_inp[num_samples + idx] = ptr_time_in[2 * idx + 2]; + ptr_esbr_inp[num_samples + idx + 1] = 0; + } + iusace_complex_fft_2048(ptr_esbr_inp, ptr_scratch_fft); + *bin1 = ixheaace_get_pitch_bin(ptr_esbr_inp, ptr_sbr_table, is_4_1); + + for (idx = 0; idx < num_samples; idx += 2) { + ptr_esbr_inp[idx] = ptr_time_in[2 * idx + 1]; + ptr_esbr_inp[idx + 1] = 0; + ptr_esbr_inp[num_samples + idx] = ptr_time_in[2 * idx + 3]; + ptr_esbr_inp[num_samples + idx + 1] = 0; + } + iusace_complex_fft_2048(ptr_esbr_inp, ptr_scratch_fft); + *bin2 = ixheaace_get_pitch_bin(ptr_esbr_inp, ptr_sbr_table, is_4_1); + } else if (num_samples == IXHEAACE_MAX_NUM_SAMPLES) { + memset(ptr_esbr_inp_i, 0, num_samples * sizeof(ptr_esbr_inp_i[0])); + for (idx = 0; idx < num_samples; idx += 2) { + ptr_esbr_inp[idx / 2] = ptr_time_in[2 * idx]; + ptr_esbr_inp[(num_samples + idx) / 2] = ptr_time_in[2 * idx + 2]; + } + iusace_complex_fft_4096(ptr_esbr_inp, ptr_esbr_inp_i, ptr_scratch_fft); + *bin1 = ixheaace_get_pitch_bin_deint(ptr_esbr_inp, ptr_esbr_inp_i, ptr_sbr_table, is_4_1); + + memset(ptr_esbr_inp_i, 0, num_samples * sizeof(ptr_esbr_inp_i[0])); + for (idx = 0; idx < num_samples; idx += 2) { + ptr_esbr_inp[idx / 2] = ptr_time_in[2 * idx + 1]; + ptr_esbr_inp[(num_samples + idx) / 2] = ptr_time_in[2 * idx + 3]; + } + iusace_complex_fft_4096(ptr_esbr_inp, ptr_esbr_inp_i, ptr_scratch_fft); + *bin2 = ixheaace_get_pitch_bin_deint(ptr_esbr_inp, ptr_esbr_inp_i, ptr_sbr_table, is_4_1); + } + } + return IA_NO_ERROR; +} static IA_ERRORCODE ixheaace_update_esbr_ext_data( FLOAT32 *ptr_time_in, ixheaace_pstr_sbr_config_data pstr_sbr_cfg, FLOAT32 *ptr_esbr_scr, ixheaace_str_esbr_bs_data *pstr_esbr, WORD32 transient_info[][3], @@ -582,6 +718,167 @@ static IA_ERRORCODE ixheaace_update_esbr_ext_data( return IA_NO_ERROR; } +static VOID ixheaace_update_harmonic_sbr_data( + WORD32 transient_info[][3], WORD32 coupling, + struct ixheaace_str_sbr_env_data *pstr_sbr_env_left, + struct ixheaace_str_sbr_env_data *pstr_sbr_env_right, WORD32 num_channels) { + WORD32 bin, bin1; + if (1 == num_channels) { + bin = pstr_sbr_env_left->sbr_pitchin_bins; + if (transient_info[0][1] != 0) { + pstr_sbr_env_left->sbr_preprocessing = 1; + } else { + pstr_sbr_env_left->sbr_preprocessing = 0; + } + + if (transient_info[0][1] != 0 && bin != -1) { + pstr_sbr_env_left->sbr_oversampling_flag = 1; + pstr_sbr_env_left->sbr_patching_mode = 0; + pstr_sbr_env_left->sbr_pitchin_bins_flag = 1; + pstr_sbr_env_left->sbr_pitchin_bins = min(bin, 127); + } else if (bin != -1) { + pstr_sbr_env_left->sbr_oversampling_flag = 0; + pstr_sbr_env_left->sbr_patching_mode = 0; + pstr_sbr_env_left->sbr_pitchin_bins_flag = 1; + pstr_sbr_env_left->sbr_pitchin_bins = min(bin, 127); + } else if (transient_info[0][1] != 0) { + pstr_sbr_env_left->sbr_oversampling_flag = 1; + pstr_sbr_env_left->sbr_patching_mode = 0; + pstr_sbr_env_left->sbr_pitchin_bins = 0; + } else { + pstr_sbr_env_left->sbr_patching_mode = 1; + } + } else { + pstr_sbr_env_left->sbr_coupling = coupling; + pstr_sbr_env_right->sbr_coupling = coupling; + bin = pstr_sbr_env_left->sbr_pitchin_bins; + + bin1 = pstr_sbr_env_right->sbr_pitchin_bins; + + if (coupling) { + pstr_sbr_env_right->sbr_preprocessing = 1; + if ((transient_info[0][1] != 0 || transient_info[1][1] != 0)) { + pstr_sbr_env_left->sbr_preprocessing = 1; + } else { + pstr_sbr_env_left->sbr_preprocessing = 0; + } + if ((transient_info[0][1] != 0 || transient_info[1][1] != 0) && bin != -1) { + pstr_sbr_env_left->sbr_oversampling_flag = 1; + pstr_sbr_env_left->sbr_patching_mode = 0; + pstr_sbr_env_left->sbr_pitchin_bins_flag = 1; + bin = min(bin, bin1); + pstr_sbr_env_left->sbr_pitchin_bins = min(bin, 127); + } else if (bin != -1) { + pstr_sbr_env_left->sbr_oversampling_flag = 0; + pstr_sbr_env_left->sbr_patching_mode = 0; + pstr_sbr_env_left->sbr_pitchin_bins_flag = 1; + bin = min(bin, bin1); + pstr_sbr_env_left->sbr_pitchin_bins = min(bin, 127); + } else if ((transient_info[0][1] != 0 || transient_info[1][1] != 0)) { + pstr_sbr_env_left->sbr_oversampling_flag = 1; + pstr_sbr_env_left->sbr_patching_mode = 0; + pstr_sbr_env_left->sbr_pitchin_bins_flag = 0; + } else { + pstr_sbr_env_left->sbr_patching_mode = 1; + } + } else { + pstr_sbr_env_left->sbr_preprocessing = 0; + pstr_sbr_env_right->sbr_preprocessing = 0; + if ((transient_info[0][1] != 0 || transient_info[1][1] != 0)) { + pstr_sbr_env_left->sbr_preprocessing = 1; + pstr_sbr_env_right->sbr_preprocessing = 1; + } + + if (transient_info[0][1] != 0 && bin != -1) { + pstr_sbr_env_left->sbr_oversampling_flag = 1; + pstr_sbr_env_left->sbr_patching_mode = 0; + pstr_sbr_env_left->sbr_pitchin_bins_flag = 1; + bin = min(bin, bin1); + pstr_sbr_env_left->sbr_pitchin_bins = min(bin, 127); + } else if (bin != -1) { + pstr_sbr_env_left->sbr_oversampling_flag = 0; + pstr_sbr_env_left->sbr_patching_mode = 0; + pstr_sbr_env_left->sbr_pitchin_bins_flag = 1; + pstr_sbr_env_left->sbr_pitchin_bins = min(bin, 127); + } else if (transient_info[0][1] != 0) { + pstr_sbr_env_left->sbr_oversampling_flag = 1; + pstr_sbr_env_left->sbr_patching_mode = 0; + pstr_sbr_env_left->sbr_pitchin_bins_flag = 0; + } else { + pstr_sbr_env_left->sbr_patching_mode = 1; + } + + if (transient_info[1][1] != 0 && bin1 != -1) { + pstr_sbr_env_right->sbr_oversampling_flag = 1; + pstr_sbr_env_right->sbr_patching_mode = 0; + pstr_sbr_env_right->sbr_pitchin_bins_flag = 1; + pstr_sbr_env_right->sbr_pitchin_bins = bin1 < 127 ? bin1 : 127; + } else if (bin1 != -1) { + pstr_sbr_env_right->sbr_oversampling_flag = 0; + pstr_sbr_env_right->sbr_patching_mode = 0; + pstr_sbr_env_right->sbr_pitchin_bins_flag = 1; + pstr_sbr_env_right->sbr_pitchin_bins = bin1 < 127 ? bin1 : 127; + } else if (transient_info[1][1] != 0) { + pstr_sbr_env_right->sbr_oversampling_flag = 1; + pstr_sbr_env_right->sbr_patching_mode = 0; + pstr_sbr_env_right->sbr_pitchin_bins_flag = 0; + } else { + pstr_sbr_env_right->sbr_patching_mode = 1; + } + } + } +} + +VOID ixheaace_esbr_qmf_init(ia_sbr_qmf_filter_bank_struct *pstr_codec_qmf_bank, + WORD32 sbr_ratio_idx, WORD32 output_frame_size) { + pstr_codec_qmf_bank->pstr_qmf_dec_tabs = + (ixheaace_str_qmf_dec_tabs_struct *)&ixheaace_str_aac_qmf_tabs; + memset( + pstr_codec_qmf_bank->anal_filter_states_32, 0, + sizeof(pstr_codec_qmf_bank->anal_filter_states_32[0]) * IXHEAACE_QMF_FILTER_STATE_ANA_SIZE); + pstr_codec_qmf_bank->num_time_slots = (WORD16)(output_frame_size / 64); + pstr_codec_qmf_bank->ptr_filter_pos_32 = ixheaace_str_aac_qmf_tabs.esbr_qmf_c; + pstr_codec_qmf_bank->ptr_state_new_samples_pos_low_32 = + pstr_codec_qmf_bank->anal_filter_states_32; + pstr_codec_qmf_bank->ptr_ana_win_coeff_32 = ixheaace_str_aac_qmf_tabs.esbr_qmf_c; + + switch (sbr_ratio_idx) { + case USAC_SBR_RATIO_INDEX_2_1: + pstr_codec_qmf_bank->no_channels = 32; + pstr_codec_qmf_bank->ptr_esbr_cos_twiddle = + ixheaace_str_aac_qmf_tabs.esbr_sin_cos_twiddle_l32; + pstr_codec_qmf_bank->ptr_esbr_alt_sin_twiddle = + ixheaace_str_aac_qmf_tabs.esbr_alt_sin_twiddle_l32; + pstr_codec_qmf_bank->ptr_esbr_t_cos = ixheaace_str_aac_qmf_tabs.esbr_t_cos_sin_l32; + break; + case USAC_SBR_RATIO_INDEX_8_3: + pstr_codec_qmf_bank->no_channels = 24; + pstr_codec_qmf_bank->ptr_filter_pos_32 = ixheaace_str_aac_qmf_tabs.esbr_qmf_c_24; + pstr_codec_qmf_bank->ptr_ana_win_coeff_32 = ixheaace_str_aac_qmf_tabs.esbr_qmf_c_24; + pstr_codec_qmf_bank->ptr_esbr_cos_twiddle = + ixheaace_str_aac_qmf_tabs.esbr_sin_cos_twiddle_l24; + pstr_codec_qmf_bank->ptr_esbr_alt_sin_twiddle = + ixheaace_str_aac_qmf_tabs.esbr_alt_sin_twiddle_l24; + pstr_codec_qmf_bank->ptr_esbr_t_cos = ixheaace_str_aac_qmf_tabs.esbr_t_cos_sin_l24; + break; + case USAC_SBR_RATIO_INDEX_4_1: + pstr_codec_qmf_bank->no_channels = 16; + pstr_codec_qmf_bank->ptr_esbr_cos_twiddle = + ixheaace_str_aac_qmf_tabs.esbr_sin_cos_twiddle_l16; + pstr_codec_qmf_bank->ptr_esbr_alt_sin_twiddle = + ixheaace_str_aac_qmf_tabs.esbr_alt_sin_twiddle_l16; + pstr_codec_qmf_bank->ptr_esbr_t_cos = ixheaace_str_aac_qmf_tabs.esbr_t_cos_sin_l16; + break; + default: + pstr_codec_qmf_bank->no_channels = 32; + pstr_codec_qmf_bank->ptr_esbr_cos_twiddle = + ixheaace_str_aac_qmf_tabs.esbr_sin_cos_twiddle_l32; + pstr_codec_qmf_bank->ptr_esbr_alt_sin_twiddle = + ixheaace_str_aac_qmf_tabs.esbr_alt_sin_twiddle_l32; + pstr_codec_qmf_bank->ptr_esbr_t_cos = ixheaace_str_aac_qmf_tabs.esbr_t_cos_sin_l32; + break; + } +} VOID ixheaace_esbr_qmfanal32_winadd(FLOAT32 *ptr_inp1, FLOAT32 *ptr_inp2, FLOAT32 *ptr_qmf1, FLOAT32 *ptr_qmf2, FLOAT32 *ptr_out, WORD32 num_band_anal_qmf) { @@ -839,7 +1136,7 @@ VOID ixheaace_esbr_postradixcompute2(FLOAT32 *ptr_y, FLOAT32 *ptr_x, ptr_y3 = ptr_y2 + (WORD32)(npoints >> 2); for (k = 0; k < 2; k++) { - for (i = 0; i> 1; i += 8) { + for (i = 0; i < npoints >> 1; i += 8) { h2 = (WORD32)*ptr_dig_rev_tbl++ / 4; x_0 = *ptr_x0++; @@ -932,7 +1229,7 @@ VOID ixheaace_esbr_postradixcompute4(FLOAT32 *ptr_y, FLOAT32 *ptr_x, ptr_y3 = ptr_y2 + (WORD32)(npoints >> 1); for (k = 0; k < 2; k++) { - for (i = 0; i> 1; i += 8) { + for (i = 0; i < npoints >> 1; i += 8) { h2 = (WORD32)*ptr_dig_rev_tbl++ / 4; x_0 = *ptr_x0++; x_1 = *ptr_x0++; @@ -1021,6 +1318,472 @@ VOID ixheaace_esbr_postradixcompute4(FLOAT32 *ptr_y, FLOAT32 *ptr_x, } } +VOID ixheaace_esbr_cos_sin_mod(FLOAT32 *subband, ia_sbr_qmf_filter_bank_struct *pstr_qmf_bank, + FLOAT32 *ptr_twiddle, FLOAT32 *ptr_dig_rev_tbl) { + WORD32 z; + FLOAT32 temp[128] = {0}; + + FLOAT32 re2, re3; + FLOAT32 wim, wre; + + WORD32 i, M_2; + WORD32 M = pstr_qmf_bank->no_channels / 2; + + const FLOAT32 *ptr_sin; + const FLOAT32 *ptr_sin_cos; + + FLOAT32 subband_tmp[128] = {0}; + FLOAT32 re; + FLOAT32 im; + FLOAT32 *ptr_subband, *ptr_subband1; + FLOAT32 *ptr_subband_t, *ptr_subband1_t; + FLOAT32 *ptr_subband2, *ptr_subband12; + FLOAT32 *ptr_subband_t2, *ptr_subband1_t2; + + M_2 = M / 2; + + ptr_sin_cos = pstr_qmf_bank->ptr_esbr_cos_twiddle; + + ptr_subband = &subband[0]; + ptr_subband1 = &subband[2 * M - 1]; + ptr_subband_t = subband_tmp; + ptr_subband1_t = &subband_tmp[2 * M - 1]; + + ptr_subband2 = &subband[64]; + ptr_subband12 = &subband[2 * M - 1 + 64]; + ptr_subband_t2 = &subband_tmp[64]; + ptr_subband1_t2 = &subband_tmp[2 * M - 1 + 64]; + + i = (M_2 >> 1) - 1; + while (i >= 0) { + re = *ptr_subband++; + im = *ptr_subband1--; + + wim = *ptr_sin_cos++; + wre = *ptr_sin_cos++; + + *ptr_subband_t++ = (re * wre) + (im * wim); + *ptr_subband_t++ = (im * wre) - (re * wim); + + re = *ptr_subband2++; + im = *ptr_subband12--; + + *ptr_subband_t2++ = (im * wim) - (re * wre); + *ptr_subband_t2++ = (re * wim) + (im * wre); + + re = *ptr_subband1--; + im = *ptr_subband++; + + wim = *ptr_sin_cos++; + wre = *ptr_sin_cos++; + + *ptr_subband1_t-- = (im * wre) - (re * wim); + *ptr_subband1_t-- = (re * wre) + (im * wim); + + re = *ptr_subband12--; + im = *ptr_subband2++; + + *ptr_subband1_t2-- = (re * wim) + (im * wre); + *ptr_subband1_t2-- = (im * wim) - (re * wre); + + re = *ptr_subband++; + im = *ptr_subband1--; + + wim = *ptr_sin_cos++; + wre = *ptr_sin_cos++; + + *ptr_subband_t++ = (re * wre) + (im * wim); + *ptr_subband_t++ = (im * wre) - (re * wim); + + re = *ptr_subband2++; + im = *ptr_subband12--; + + *ptr_subband_t2++ = (im * wim) - (re * wre); + *ptr_subband_t2++ = (re * wim) + (im * wre); + + re = *ptr_subband1--; + im = *ptr_subband++; + + wim = *ptr_sin_cos++; + wre = *ptr_sin_cos++; + + *ptr_subband1_t-- = (im * wre) - (re * wim); + *ptr_subband1_t-- = (re * wre) + (im * wim); + + re = *ptr_subband12--; + im = *ptr_subband2++; + + *ptr_subband1_t2-- = (re * wim) + (im * wre); + *ptr_subband1_t2-- = (im * wim) - (re * wre); + + i--; + } + + switch (M) { + case M_32: + ixheaace_esbr_radix4bfly(ptr_twiddle, subband_tmp, 1, 8); + ixheaace_esbr_radix4bfly(ptr_twiddle + 48, subband_tmp, 4, 2); + ixheaace_esbr_postradixcompute2(subband, subband_tmp, ptr_dig_rev_tbl, 32); + + ixheaace_esbr_radix4bfly(ptr_twiddle, &subband_tmp[64], 1, 8); + ixheaace_esbr_radix4bfly(ptr_twiddle + 48, &subband_tmp[64], 4, 2); + ixheaace_esbr_postradixcompute2(&subband[64], &subband_tmp[64], ptr_dig_rev_tbl, 32); + break; + + case M_16: + ixheaace_esbr_radix4bfly(ptr_twiddle, subband_tmp, 1, 4); + ixheaace_esbr_postradixcompute4(subband, subband_tmp, ptr_dig_rev_tbl, 16); + + ixheaace_esbr_radix4bfly(ptr_twiddle, &subband_tmp[64], 1, 4); + ixheaace_esbr_postradixcompute4(&subband[64], &subband_tmp[64], ptr_dig_rev_tbl, 16); + break; + + case M_12: + + for (z = 0; z < (pstr_qmf_bank->no_channels >> 1); z++) { + temp[z] = subband_tmp[2 * z]; + temp[12 + z] = subband_tmp[2 * z + 1]; + } + + // convert re and im data to interleave + FLOAT32 intermediate[24]; + WORD32 cnt = 0; + while (cnt < M_12) { + intermediate[2 * cnt] = temp[cnt]; + intermediate[2 * cnt + 1] = temp[12 + cnt]; + cnt++; + } + + iusace_complex_fft_p3_no_scratch(intermediate, 12); + // de-interleave + for (cnt = 0; cnt < 12; cnt++) { + temp[cnt] = intermediate[2 * cnt]; + temp[12 + cnt] = intermediate[2 * cnt + 1]; + } + + z = 0; + while (z < (pstr_qmf_bank->no_channels >> 1)) { + subband[2 * z] = temp[z]; + subband[2 * z + 1] = temp[z + 12]; + z++; + } + + z = 0; + while (z < (pstr_qmf_bank->no_channels >> 1)) { + temp[z] = subband_tmp[64 + 2 * z]; + temp[12 + z] = subband_tmp[64 + 2 * z + 1]; + z++; + } + + // convert re and im data to interleave + cnt = 0; + while (cnt < 12) { + intermediate[2 * cnt] = temp[cnt]; + intermediate[2 * cnt + 1] = temp[12 + cnt]; + cnt++; + } + iusace_complex_fft_p3_no_scratch(intermediate, 12); + // de-interleave + + cnt = 0; + while (cnt < 12) { + temp[cnt] = intermediate[2 * cnt]; + temp[12 + cnt] = intermediate[2 * cnt + 1]; + cnt++; + } + + z = 0; + while (z < (pstr_qmf_bank->no_channels >> 1)) { + subband[64 + 2 * z] = temp[z]; + subband[64 + 2 * z + 1] = temp[z + 12]; + z++; + } + break; + + default: + z = 0; + while (z < (pstr_qmf_bank->no_channels >> 1)) { + temp[z] = subband_tmp[2 * z]; + temp[8 + z] = subband_tmp[2 * z + 1]; + z++; + } + + FLOAT32 scratch[1024]; + cnt = 0; + while (cnt < 8) { + intermediate[2 * cnt] = temp[cnt]; + intermediate[2 * cnt + 1] = temp[8 + cnt]; + cnt++; + } + + iusace_complex_fft_p2(intermediate, 8, scratch); + // de-interleave + cnt = 0; + while (cnt < 8) { + temp[cnt] = intermediate[2 * cnt]; + temp[8 + cnt] = intermediate[2 * cnt + 1]; + cnt++; + } + + z = 0; + while (z < (pstr_qmf_bank->no_channels >> 1)) { + subband[2 * z] = temp[z]; + subband[2 * z + 1] = temp[z + 8]; + z++; + } + z = 0; + while (z < (pstr_qmf_bank->no_channels >> 1)) { + temp[z] = subband_tmp[64 + 2 * z]; + temp[8 + z] = subband_tmp[64 + 2 * z + 1]; + z++; + } + + // convert re and im data to interleave + cnt = 0; + while (cnt < 8) { + intermediate[2 * cnt] = temp[cnt]; + intermediate[2 * cnt + 1] = temp[8 + cnt]; + cnt++; + } + + iusace_complex_fft_p2(intermediate, 8, scratch); + + // de-interleave + cnt = 0; + while (cnt < 8) { + temp[cnt] = intermediate[2 * cnt]; + temp[8 + cnt] = intermediate[2 * cnt + 1]; + cnt++; + } + + z = 0; + while (z < (pstr_qmf_bank->no_channels >> 1)) { + subband[64 + 2 * z] = temp[z]; + subband[64 + 2 * z + 1] = temp[8 + z]; + z++; + } + break; + } + + ptr_subband = &subband[0]; + ptr_subband1 = &subband[2 * M - 1]; + + re = *ptr_subband1; + + *ptr_subband = *ptr_subband / 2; + ptr_subband++; + *ptr_subband1 = -(*ptr_subband / 2); + ptr_subband1--; + + ptr_sin = pstr_qmf_bank->ptr_esbr_alt_sin_twiddle; + + wim = *ptr_sin++; + wre = *ptr_sin++; + + im = *ptr_subband1; + + *ptr_subband1-- = (re * wre) + (im * wim); + *ptr_subband++ = (im * wre) - (re * wim); + + ptr_subband2 = &subband[64]; + ptr_subband12 = &subband[2 * M - 1 + 64]; + + re = *ptr_subband12; + + *ptr_subband12-- = -(*ptr_subband2 / 2); + + *ptr_subband2 = ptr_subband2[1] / 2; + + ptr_subband2++; + + im = *ptr_subband12; + + *ptr_subband2++ = -((re * wre) + (im * wim)); + *ptr_subband12-- = (re * wim) - (im * wre); + + i = (M_2 - 2); + while (i >= 0) { + im = ptr_subband[0]; + + re = ptr_subband[1]; + + re2 = *ptr_subband1; + + *ptr_subband++ = (re * wim) + (im * wre); + *ptr_subband1-- = (im * wim) - (re * wre); + + im = ptr_subband2[0]; + + re = ptr_subband2[1]; + + re3 = *ptr_subband12; + + *ptr_subband12-- = -((re * wim) + (im * wre)); + *ptr_subband2++ = (re * wre) - (im * wim); + + wim = *ptr_sin++; + wre = *ptr_sin++; + im = ptr_subband1[0]; + + *ptr_subband1-- = (re2 * wre) + (im * wim); + *ptr_subband++ = (im * wre) - (re2 * wim); + + im = ptr_subband12[0]; + + *ptr_subband2++ = -((re3 * wre) + (im * wim)); + *ptr_subband12-- = (re3 * wim) - (im * wre); + i--; + } +} + +static VOID ixheaace_esbr_fwd_modulation(const FLOAT32 *ptr_time_sample_buf, + FLOAT32 *ptr_in_real_subband, + FLOAT32 *ptr_in_imag_subband, + ia_sbr_qmf_filter_bank_struct *pstr_qmf_bank, + ixheaace_str_qmf_dec_tabs_struct *pstr_qmf_dec_tabs) { + WORD32 i; + const FLOAT32 *ptr_time_sample_buf1 = &ptr_time_sample_buf[2 * pstr_qmf_bank->no_channels - 1]; + FLOAT32 temp1, temp2; + FLOAT32 *ptr_real_subband = ptr_in_real_subband; + FLOAT32 *ptr_imag_subband = ptr_in_imag_subband; + const FLOAT32 *ptr_cos; + + for (i = pstr_qmf_bank->no_channels - 1; i >= 0; i--) { + temp1 = *ptr_time_sample_buf++ / 16.0f; + temp2 = *ptr_time_sample_buf1-- / 16.0f; + *ptr_real_subband++ = (temp1 - temp2); + *ptr_imag_subband++ = (temp1 + temp2); + } + + ixheaace_esbr_cos_sin_mod(ptr_in_real_subband, pstr_qmf_bank, pstr_qmf_dec_tabs->esbr_w_16, + pstr_qmf_dec_tabs->dig_rev_tab_4_16); + + ptr_cos = pstr_qmf_bank->ptr_esbr_t_cos; + + i = (pstr_qmf_bank->usb - pstr_qmf_bank->lsb - 1); + while (i >= 0) { + FLOAT32 cosh, sinh; + FLOAT32 re, im; + + re = *ptr_in_real_subband; + im = *ptr_in_imag_subband; + cosh = *ptr_cos++; + sinh = *ptr_cos++; + *ptr_in_real_subband++ = 2 * ((re * cosh) + (im * sinh)); + *ptr_in_imag_subband++ = 2 * ((im * cosh) - (re * sinh)); + i--; + } +} + +VOID ixheaace_esbr_analysis_filt_block( + ia_sbr_qmf_filter_bank_struct *pstr_codec_qmf_bank, + ixheaace_str_qmf_dec_tabs_struct *pstr_qmf_dec_tabs, FLOAT32 *ptr_core_coder_samples, + FLOAT32 qmf_buf_real[IXHEAACE_TIMESLOT_BUFFER_SIZE + 2 * 32][IXHEAACE_NUM_QMF_SYNTH_CHANNELS], + FLOAT32 qmf_buf_imag[IXHEAACE_TIMESLOT_BUFFER_SIZE + 2 * 32][IXHEAACE_NUM_QMF_SYNTH_CHANNELS], + WORD32 op_delay) { + FLOAT32 *ptr_filt_states; + FLOAT32 *ptr_filt_states_1; + FLOAT32 *ptr_filt_states_2; + FLOAT32 *ptr_temp; + FLOAT32 *ptr_win_coeffs_1; + FLOAT32 *ptr_win_coeffs_2; + FLOAT32 *ptr_win_coeffs; + FLOAT32 *ptr_loc_qmf_buf_real; + FLOAT32 *ptr_loc_qmf_buf_imag; + FLOAT32 local_qmf_buffer[128] = {0}; + FLOAT32 anal_buf[2 * 32] = {0}; + WORD32 idx, z; + WORD32 core_syn_ch_index; + FLOAT32 gain; + WORD32 filt_offset; + WORD32 num_columns; + + ia_sbr_qmf_filter_bank_struct *pstr_qmf_anal_bank = pstr_codec_qmf_bank; + ptr_filt_states = pstr_qmf_anal_bank->ptr_state_new_samples_pos_low_32; + ptr_win_coeffs_1 = (FLOAT32 *)pstr_qmf_anal_bank->ptr_filter_pos_32; + num_columns = pstr_qmf_anal_bank->no_channels; + + switch (num_columns) { + case 16: + ptr_win_coeffs_2 = ptr_win_coeffs_1 + 64; + gain = 128.0f; + filt_offset = 64; + break; + case 24: + ptr_win_coeffs_2 = ptr_win_coeffs_1 + 24; + gain = 12.0f; + filt_offset = 24; + break; + case 32: + ptr_win_coeffs_2 = ptr_win_coeffs_1 + 64; + gain = 256.0f; + filt_offset = 64; + break; + default: + ptr_win_coeffs_2 = ptr_win_coeffs_1 + 64; + gain = 256.0f; + filt_offset = 64; + break; + } + gain = 1.0f / gain; + + pstr_qmf_anal_bank->usb = (WORD16)num_columns; + + ptr_loc_qmf_buf_real = &local_qmf_buffer[0]; + ptr_loc_qmf_buf_imag = &local_qmf_buffer[64]; + + ptr_filt_states_1 = pstr_qmf_anal_bank->anal_filter_states_32; + ptr_filt_states_2 = pstr_qmf_anal_bank->anal_filter_states_32 + num_columns; + + idx = 0; + while (idx < pstr_codec_qmf_bank->num_time_slots) { + for (z = 0; z < num_columns; z++) { + ptr_filt_states[num_columns - 1 - z] = ptr_core_coder_samples[z]; + } + + ixheaace_esbr_qmfanal32_winadd(ptr_filt_states_1, ptr_filt_states_2, ptr_win_coeffs_1, + ptr_win_coeffs_2, anal_buf, num_columns); + + ptr_core_coder_samples += num_columns; + + ptr_filt_states -= num_columns; + if (ptr_filt_states < pstr_qmf_anal_bank->anal_filter_states_32) { + ptr_filt_states = + pstr_qmf_anal_bank->anal_filter_states_32 + 10 * num_columns - num_columns; + } + + ptr_temp = ptr_filt_states_1; + ptr_filt_states_1 = ptr_filt_states_2; + ptr_filt_states_2 = ptr_temp; + + ptr_win_coeffs_1 += filt_offset; + ptr_win_coeffs_2 += filt_offset; + + ptr_win_coeffs = ptr_win_coeffs_1; + ptr_win_coeffs_1 = ptr_win_coeffs_2; + ptr_win_coeffs_2 = ptr_win_coeffs; + + if (ptr_win_coeffs_2 > (pstr_qmf_anal_bank->ptr_ana_win_coeff_32 + filt_offset * 10)) { + ptr_win_coeffs_1 = (FLOAT32 *)pstr_qmf_anal_bank->ptr_ana_win_coeff_32; + ptr_win_coeffs_2 = (FLOAT32 *)pstr_qmf_anal_bank->ptr_ana_win_coeff_32 + filt_offset; + } + + ixheaace_esbr_fwd_modulation(anal_buf, &ptr_loc_qmf_buf_real[0], &ptr_loc_qmf_buf_imag[0], + pstr_qmf_anal_bank, pstr_qmf_dec_tabs); + + core_syn_ch_index = num_columns; + + for (z = 0; z < core_syn_ch_index; z++) { + qmf_buf_real[op_delay + idx][z] = ((FLOAT32)ptr_loc_qmf_buf_real[z] * gain); + qmf_buf_imag[op_delay + idx][z] = ((FLOAT32)ptr_loc_qmf_buf_imag[z] * gain); + } + + idx++; + } + + pstr_qmf_anal_bank->ptr_filter_pos_32 = ptr_win_coeffs_1; + pstr_qmf_anal_bank->ptr_state_new_samples_pos_low_32 = ptr_filt_states; +} IA_ERRORCODE ixheaace_extract_sbr_envelope(FLOAT32 *ptr_in_time, FLOAT32 *ptr_core_buf, UWORD32 time_sn_stride, ixheaace_pstr_sbr_enc pstr_env_enc, @@ -1074,7 +1837,10 @@ IA_ERRORCODE ixheaace_extract_sbr_envelope(FLOAT32 *ptr_in_time, FLOAT32 *ptr_co WORD32 max_quant_error; ixheaace_str_esbr_bs_data str_esbr; WORD32 samp_ratio_fac = DOWNSAMPLE_FAC_2_1; - + if ((pstr_env_enc->str_sbr_cfg.sbr_codec == USAC_SBR) && + (pstr_env_enc->str_sbr_cfg.sbr_ratio_idx == USAC_SBR_RATIO_INDEX_4_1)) { + samp_ratio_fac = DOWNSAMPLE_FAC_4_1; + } if ((n_in_channels > IXHEAACE_MAX_CH_IN_BS_ELE) || (n_in_channels < num_channels) || (n_in_channels <= 0) || (num_channels <= 0)) { return IA_EXHEAACE_EXE_FATAL_SBR_INVALID_IN_CHANNELS; @@ -1092,7 +1858,48 @@ IA_ERRORCODE ixheaace_extract_sbr_envelope(FLOAT32 *ptr_in_time, FLOAT32 *ptr_co IXHEAACE_MAX_CH_IN_BS_ELE * MAXIMUM_NUM_ENVELOPE_VALUES * 2; ch++; } + if ((pstr_sbr_cfg->sbr_codec == USAC_SBR) && (pstr_sbr_hdr->sbr_harmonic)) { + WORD32 num_sbr_samples = 2048; + if (pstr_sbr_cfg->sbr_ratio_idx == USAC_SBR_RATIO_INDEX_4_1) { + num_sbr_samples = IXHEAACE_MAX_NUM_SAMPLES; + } + err_code = ixheaace_hbe_get_pitch_bins( + ptr_in_time, pstr_sbr_cfg, pstr_env_ch[0]->str_sbr_extract_env.ptr_r_buffer[0], + ptr_sbr_tab, time_sn_stride, num_sbr_samples, &pstr_env_0->sbr_pitchin_bins, + n_in_channels == 1 ? NULL : &pstr_env_1->sbr_pitchin_bins); + if (err_code) return err_code; + WORD32 op_delay, codec_x_delay, num_time_slots; + op_delay = IXHEAACE_OP_DELAY_OFFSET; + codec_x_delay = IXHEAACE_ESBR_HBE_DELAY_OFFSET; + if (pstr_sbr_cfg->sbr_ratio_idx == USAC_SBR_RATIO_INDEX_4_1) { + op_delay = 2 * op_delay; + codec_x_delay = 2 * codec_x_delay; + } + + WORD32 eff_offset = op_delay + IXHEAACE_SBR_HF_ADJ_OFFSET; + WORD32 memmove_sz1 = (eff_offset + codec_x_delay) * + sizeof(pstr_env_ch[0]->pstr_hbe_enc->qmf_buf_real[0][0]) * + MAX_QMF_TIME_SLOTS; + WORD32 memmove_sz2 = eff_offset * + sizeof(pstr_env_ch[0]->pstr_hbe_enc->ph_vocod_qmf_real[0][0]) * + MAX_QMF_TIME_SLOTS; + + for (ch = 0; ch < n_in_channels; ch++) { + ixheaace_str_hbe_enc *pstr_hbe_enc = pstr_env_ch[ch]->pstr_hbe_enc; + num_time_slots = + pstr_env_ch[ch]->str_sbr_qmf.num_time_slots * pstr_env_ch[ch]->str_sbr_qmf.rate; + + memmove(pstr_hbe_enc->qmf_buf_real[0], pstr_hbe_enc->qmf_buf_real[num_time_slots], + memmove_sz1); + memmove(pstr_hbe_enc->qmf_buf_imag[0], pstr_hbe_enc->qmf_buf_imag[num_time_slots], + memmove_sz1); + memmove(pstr_hbe_enc->ph_vocod_qmf_real[0], pstr_hbe_enc->ph_vocod_qmf_real[num_time_slots], + memmove_sz2); + memmove(pstr_hbe_enc->ph_vocod_qmf_imag, pstr_hbe_enc->ph_vocod_qmf_imag + num_time_slots, + memmove_sz2); + } + } i = 0; while (i < MAXIMUM_NUM_NOISE_VALUES) { res[i] = FREQ_RES_HIGH; @@ -1105,16 +1912,195 @@ IA_ERRORCODE ixheaace_extract_sbr_envelope(FLOAT32 *ptr_in_time, FLOAT32 *ptr_co while (ch < n_in_channels) { ixheaace_str_sbr_extr_env *pstr_sbr_extract_env = &(pstr_env_ch[ch]->str_sbr_extract_env); - ixheaace_sbr_analysis_filtering( - ptr_in_time ? ptr_in_time + ch : NULL, time_sn_stride, pstr_sbr_extract_env->ptr_r_buffer, - pstr_sbr_extract_env->ptr_i_buffer, &pstr_env_ch[ch]->str_sbr_qmf, - ptr_sbr_tab->ptr_qmf_tab, - pstr_env_ch[ch]->str_sbr_qmf.num_time_slots * pstr_env_ch[ch]->str_sbr_qmf.rate, - pstr_sbr_cfg->is_ld_sbr, (FLOAT32 *)ptr_sbr_scratch); + if (pstr_ps_enc) { + ixheaace_sbr_analysis_filtering( + ptr_in_time ? ptr_in_time + ch : NULL, IXHEAACE_MAX_CH_IN_BS_ELE, + pstr_sbr_extract_env->ptr_r_buffer, pstr_sbr_extract_env->ptr_i_buffer, + &pstr_env_ch[ch]->str_sbr_qmf, ptr_sbr_tab->ptr_qmf_tab, + pstr_env_ch[ch]->str_sbr_qmf.num_time_slots * pstr_env_ch[ch]->str_sbr_qmf.rate, + pstr_sbr_cfg->is_ld_sbr, (FLOAT32 *)ptr_sbr_scratch); + } else { + ixheaace_sbr_analysis_filtering( + ptr_in_time ? ptr_in_time + ch : NULL, time_sn_stride, + pstr_sbr_extract_env->ptr_r_buffer, pstr_sbr_extract_env->ptr_i_buffer, + &pstr_env_ch[ch]->str_sbr_qmf, ptr_sbr_tab->ptr_qmf_tab, + pstr_env_ch[ch]->str_sbr_qmf.num_time_slots * pstr_env_ch[ch]->str_sbr_qmf.rate, + pstr_sbr_cfg->is_ld_sbr, (FLOAT32 *)ptr_sbr_scratch); + if ((1 == n_in_channels) && (USAC_SBR == pstr_sbr_cfg->sbr_codec) && + (pstr_sbr_hdr->sbr_pvc_active)) { + ixheaace_pvc_scratch *pstr_pvc_scr = (ixheaace_pvc_scratch *)ptr_sbr_scratch; + WORD32 ts, bd; + FLOAT32 nrg_0, nrg_1; + FLOAT32 *ptr_r_0, *ptr_r_1, *ptr_i_0, *ptr_i_1; + FLOAT32 *ptr_r_2, *ptr_r_3, *ptr_i_2, *ptr_i_3, nrg_2, nrg_3; + WORD32 pvc_rate = pstr_env_enc->pstr_pvc_enc->pvc_param.pvc_rate; + + // update header_active to send SBR header when previous PVC mode is different from + // current frame's + if (pstr_env_enc->str_sbr_hdr.sbr_pvc_mode != + pstr_env_enc->pstr_pvc_enc->pvc_param.pvc_mode) { + pstr_sbr_bs->header_active = 1; + } + + switch (pvc_rate) { + case 2: { + for (ts = 0; ts < IXHEAACE_ESBR_PVC_NUM_TS; ts++) { + ptr_r_0 = pstr_sbr_extract_env->ptr_r_buffer[pvc_rate * ts]; + ptr_r_1 = pstr_sbr_extract_env->ptr_r_buffer[pvc_rate * ts + 1]; + ptr_i_0 = pstr_sbr_extract_env->ptr_i_buffer[pvc_rate * ts]; + ptr_i_1 = pstr_sbr_extract_env->ptr_i_buffer[pvc_rate * ts + 1]; + + for (bd = 0; bd < MAX_QMF_TIME_SLOTS; bd++) { + nrg_0 = ptr_r_0[bd] * ptr_r_0[bd] + ptr_i_0[bd] * ptr_i_0[bd]; + nrg_1 = ptr_r_1[bd] * ptr_r_1[bd] + ptr_i_1[bd] * ptr_i_1[bd]; + pstr_pvc_scr->pvc_qmf_high[ts * IXHEAACE_ESBR_PVC_NUM_QMF_BANDS + bd] = + (nrg_0 + nrg_1) / 2.0f; + } + WORD32 num_low_bands = MAX_QMF_TIME_SLOTS >> 1; + for (bd = 0; bd < num_low_bands; bd++) { + pstr_pvc_scr->pvc_qmf_low[ts * num_low_bands + bd] = + pstr_pvc_scr->pvc_qmf_high[ts * IXHEAACE_ESBR_PVC_NUM_QMF_BANDS + bd]; + } + } + break; + } + case 4: { + for (ts = 0; ts < IXHEAACE_ESBR_PVC_NUM_TS; ts++) { + ptr_r_0 = pstr_sbr_extract_env->ptr_r_buffer[pvc_rate * ts]; + ptr_r_1 = pstr_sbr_extract_env->ptr_r_buffer[pvc_rate * ts + 1]; + ptr_r_2 = pstr_sbr_extract_env->ptr_r_buffer[pvc_rate * ts + 2]; + ptr_r_3 = pstr_sbr_extract_env->ptr_r_buffer[pvc_rate * ts + 3]; + ptr_i_0 = pstr_sbr_extract_env->ptr_i_buffer[pvc_rate * ts]; + ptr_i_1 = pstr_sbr_extract_env->ptr_i_buffer[pvc_rate * ts + 1]; + ptr_i_2 = pstr_sbr_extract_env->ptr_i_buffer[pvc_rate * ts + 2]; + ptr_i_3 = pstr_sbr_extract_env->ptr_i_buffer[pvc_rate * ts + 3]; + + for (bd = 0; bd < MAX_QMF_TIME_SLOTS; bd++) { + nrg_0 = ptr_r_0[bd] * ptr_r_0[bd] + ptr_i_0[bd] * ptr_i_0[bd]; + nrg_1 = ptr_r_1[bd] * ptr_r_1[bd] + ptr_i_1[bd] * ptr_i_1[bd]; + nrg_2 = ptr_r_2[bd] * ptr_r_2[bd] + ptr_i_2[bd] * ptr_i_2[bd]; + nrg_3 = ptr_r_3[bd] * ptr_r_3[bd] + ptr_i_3[bd] * ptr_i_3[bd]; + pstr_pvc_scr->pvc_qmf_high[ts * IXHEAACE_ESBR_PVC_NUM_QMF_BANDS + bd] = + (nrg_0 + nrg_1 + nrg_2 + nrg_3) / 4.0f; + } + WORD32 num_low_bands = (MAX_QMF_TIME_SLOTS >> 2); + for (bd = 0; bd < num_low_bands; bd++) { + pstr_pvc_scr->pvc_qmf_low[ts * num_low_bands + bd] = + pstr_pvc_scr->pvc_qmf_high[ts * IXHEAACE_ESBR_PVC_NUM_QMF_BANDS + bd]; + } + } + break; + } + } + pstr_env_enc->pstr_pvc_enc->pvc_param.usac_indep_flag = pstr_sbr_bs->usac_indep_flag; + err_code = ixheaace_pvc_encode_frame( + pstr_env_enc->pstr_pvc_enc, (UWORD8)pstr_env_enc->str_sbr_hdr.sbr_pvc_mode, + pstr_pvc_scr->pvc_qmf_low, pstr_pvc_scr->pvc_qmf_high, + pstr_sbr_cfg->ptr_v_k_master[0], + pstr_sbr_cfg->ptr_v_k_master[pstr_sbr_cfg->num_master] - 1); + if (err_code) { + return err_code; + } + + memcpy(&pstr_env_ch[ch]->enc_env_data.pvc_info, &pstr_env_enc->pstr_pvc_enc->pvc_bs_info, + sizeof(ixheaace_pvc_bs_info)); + } + + // COPY generated spectrum for inter-TES encoder + if ((USAC_SBR == pstr_sbr_cfg->sbr_codec) && (1 == pstr_sbr_hdr->sbr_inter_tes_active)) { + WORD32 ts, num_ts, delay; + num_ts = pstr_env_ch[ch]->str_sbr_qmf.num_time_slots; + + ixheaace_str_inter_tes_params *pstr_tes_enc = &pstr_env_ch[ch]->str_inter_tes_enc; + delay = pstr_tes_enc->op_delay + pstr_tes_enc->codec_delay + IXHEAACE_SBR_HF_ADJ_OFFSET; + ts = 0; + while (ts < num_ts) { + memcpy(pstr_tes_enc->qmf_buf_real[delay + ts], pstr_sbr_extract_env->ptr_r_buffer[ts], + IXHEAACE_QMF_CHANNELS * sizeof(pstr_tes_enc->qmf_buf_real[0][0])); + memcpy(pstr_tes_enc->qmf_buf_imag[delay + ts], pstr_sbr_extract_env->ptr_i_buffer[ts], + IXHEAACE_QMF_CHANNELS * sizeof(pstr_tes_enc->qmf_buf_imag[0][0])); + ts++; + } + } + } ch++; - } /*end ch */ + } + if ((pstr_sbr_cfg->sbr_codec == USAC_SBR) && (pstr_sbr_hdr->sbr_harmonic)) { + WORD32 dft_hbe_flag = 0; + WORD32 op_delay, codec_x_delay, num_time_slots; + WORD32 esbr_hbe_delay_offsets = IXHEAACE_ESBR_HBE_DELAY_OFFSET; + WORD32 oversampling_flag = 0; + op_delay = IXHEAACE_OP_DELAY_OFFSET; + codec_x_delay = IXHEAACE_ESBR_HBE_DELAY_OFFSET; + if (pstr_sbr_cfg->sbr_ratio_idx == USAC_SBR_RATIO_INDEX_4_1) { + op_delay = 2 * IXHEAACE_OP_DELAY_OFFSET; + codec_x_delay = 2 * codec_x_delay; + oversampling_flag = 1; + } + WORD32 eff_offset = op_delay + IXHEAACE_SBR_HF_ADJ_OFFSET; + dft_hbe_flag = pstr_sbr_hdr->hq_esbr; + ch = 0; + while (ch < n_in_channels) { + ixheaace_str_hbe_enc *pstr_hbe_enc = pstr_env_ch[ch]->pstr_hbe_enc; + pstr_hbe_enc->pstr_hbe_txposer->oversampling_flag = oversampling_flag; + num_time_slots = + pstr_env_ch[ch]->str_sbr_qmf.num_time_slots * pstr_env_ch[ch]->str_sbr_qmf.rate; + if (dft_hbe_flag == 1) { + err_code = ixheaace_dft_hbe_apply( + pstr_hbe_enc->pstr_hbe_txposer, + pstr_hbe_enc->qmf_buf_real + eff_offset + esbr_hbe_delay_offsets, + pstr_hbe_enc->qmf_buf_imag + eff_offset + esbr_hbe_delay_offsets, num_time_slots, + pstr_hbe_enc->ph_vocod_qmf_real + eff_offset, + pstr_hbe_enc->ph_vocod_qmf_imag + eff_offset, + pstr_env_ch[ch]->enc_env_data.sbr_pitchin_bins, (FLOAT32 *)ptr_sbr_scratch); + if (err_code) { + return err_code; + } + } else { + // size 4096 samples + FLOAT32 *ptr_time_data = (FLOAT32 *)ptr_sbr_scratch; + int cnt = 0; + if (0 == ch) { + while (cnt < IXHEAACE_MAX_NUM_SAMPLES) { + ptr_time_data[cnt] = pstr_env_enc->ptr_hbe_resample_buf[2 * cnt]; + cnt++; + } + } else { + while (cnt < IXHEAACE_MAX_NUM_SAMPLES) { + ptr_time_data[cnt] = pstr_env_enc->ptr_hbe_resample_buf[2 * cnt + 1]; + cnt++; + } + } + + ixheaace_esbr_analysis_filt_block(&(pstr_hbe_enc->str_codec_qmf_bank), + pstr_hbe_enc->str_codec_qmf_bank.pstr_qmf_dec_tabs, + ptr_time_data, pstr_hbe_enc->qmf_buf_real, + pstr_hbe_enc->qmf_buf_imag, + op_delay + codec_x_delay + IXHEAACE_SBR_HF_ADJ_OFFSET); + + err_code = ixheaace_qmf_hbe_apply( + pstr_hbe_enc->pstr_hbe_txposer, + pstr_hbe_enc->qmf_buf_real + eff_offset + esbr_hbe_delay_offsets, + pstr_hbe_enc->qmf_buf_imag + eff_offset + esbr_hbe_delay_offsets, num_time_slots, + pstr_hbe_enc->ph_vocod_qmf_real + eff_offset, + pstr_hbe_enc->ph_vocod_qmf_imag + eff_offset, + pstr_env_ch[ch]->enc_env_data.sbr_pitchin_bins); + if (err_code) { + return err_code; + } + + if (pstr_sbr_cfg->sbr_ratio_idx == USAC_SBR_RATIO_INDEX_4_1) { + ixheaace_hbe_repl_spec(&pstr_hbe_enc->pstr_hbe_txposer->x_over_qmf[0], + pstr_hbe_enc->ph_vocod_qmf_real + eff_offset, + pstr_hbe_enc->ph_vocod_qmf_imag + eff_offset, num_time_slots, + pstr_hbe_enc->pstr_hbe_txposer->max_stretch); + } + } + ch++; + } + } if (pstr_ps_enc && pstr_synthesis_qmf_bank) { err_code = ixheaace_encode_ps_frame( pstr_ps_enc, pstr_env_ch[0]->str_sbr_extract_env.ptr_i_buffer, @@ -1132,12 +2118,16 @@ IA_ERRORCODE ixheaace_extract_sbr_envelope(FLOAT32 *ptr_in_time, FLOAT32 *ptr_co ch = 0; while (ch < num_channels) { + ixheaace_str_hbe_enc *pstr_hbe_enc = pstr_env_ch[ch]->pstr_hbe_enc; ixheaace_str_sbr_extr_env *pstr_sbr_extract_env = &(pstr_env_ch[ch]->str_sbr_extract_env); ixheaace_get_energy_from_cplx_qmf( pstr_sbr_extract_env->ptr_y_buffer + pstr_sbr_extract_env->y_buffer_write_offset, pstr_sbr_extract_env->ptr_r_buffer, pstr_sbr_extract_env->ptr_i_buffer, - pstr_sbr_cfg->is_ld_sbr, pstr_env_ch[ch]->str_sbr_qmf.num_time_slots, samp_ratio_fac); + pstr_sbr_cfg->is_ld_sbr, pstr_env_ch[ch]->str_sbr_qmf.num_time_slots, samp_ratio_fac, + pstr_hbe_enc->qmf_buf_real, pstr_hbe_enc->qmf_buf_imag, + (IXHEAACE_OP_DELAY_OFFSET + IXHEAACE_ESBR_HBE_DELAY_OFFSET + IXHEAACE_SBR_HF_ADJ_OFFSET), + pstr_sbr_hdr->sbr_harmonic); ixheaace_calculate_tonality_quotas( &pstr_env_ch[ch]->str_ton_corr, pstr_sbr_extract_env->ptr_r_buffer, @@ -1171,7 +2161,7 @@ IA_ERRORCODE ixheaace_extract_sbr_envelope(FLOAT32 *ptr_in_time, FLOAT32 *ptr_co } } ch++; - } /*end ch */ + } if (stereo_mode == SBR_COUPLING) { if (transient_info[0][1] && transient_info[1][1]) { @@ -1320,7 +2310,7 @@ IA_ERRORCODE ixheaace_extract_sbr_envelope(FLOAT32 *ptr_in_time, FLOAT32 *ptr_co pstr_env_ch[ch]->enc_env_data.sbr_invf_mode_vec[0]; pstr_env_ch[ch]->enc_env_data.noise_band_count = pstr_env_ch[ch]->str_ton_corr.sbr_noise_floor_est.num_of_noise_bands; - } /*end ch */ + } switch (stereo_mode) { case IXHEAACE_SBR_MODE_MONO: @@ -1575,7 +2565,7 @@ IA_ERRORCODE ixheaace_extract_sbr_envelope(FLOAT32 *ptr_in_time, FLOAT32 *ptr_co pstr_env_ch[ch]->str_sbr_code_noise_floor.update = 0; } ch++; - } /*end ch */ + } err_code = ixheaace_code_envelope( ptr_scale_factor_band_nrg[0], pstr_const_frame_info[0]->freq_res, @@ -1681,7 +2671,7 @@ IA_ERRORCODE ixheaace_extract_sbr_envelope(FLOAT32 *ptr_in_time, FLOAT32 *ptr_co pstr_env_ch[ch]->str_sbr_code_env.update = 0; pstr_env_ch[ch]->str_sbr_code_noise_floor.update = 0; } - } /*end ch */ + } err_code = ixheaace_code_envelope( ptr_sfb_nrg_coupling[0], pstr_const_frame_info[0]->freq_res, @@ -1796,8 +2786,7 @@ IA_ERRORCODE ixheaace_extract_sbr_envelope(FLOAT32 *ptr_in_time, FLOAT32 *ptr_co pstr_env_1->balance = 0; } } break; - - } /* end switch(stereo_mode) */ + } if (num_channels == 1) { if (pstr_env_0->domain_vec[0] == TIME) { @@ -1832,9 +2821,56 @@ IA_ERRORCODE ixheaace_extract_sbr_envelope(FLOAT32 *ptr_in_time, FLOAT32 *ptr_co pstr_env_ch[ch]->enc_env_data.noise_level[i] = ptr_noise_level[ch][i]; i++; } + } + if ((USAC_SBR == pstr_sbr_cfg->sbr_codec) && (1 == pstr_sbr_hdr->sbr_inter_tes_active)) { + // inter-TES encoder + WORD32 idx; + for (ch = 0; ch < num_channels; ch++) { + ixheaace_str_inter_tes_params *pstr_tes_enc = &pstr_env_ch[ch]->str_inter_tes_enc; - } /*end ch */ + pstr_tes_enc->num_if_bands = pstr_env_ch[ch]->enc_env_data.noise_band_count; + pstr_tes_enc->sub_band_start = pstr_sbr_cfg->ptr_freq_band_tab[LO][0]; + pstr_tes_enc->sub_band_end = pstr_sbr_cfg->ptr_freq_band_tab[LO][pstr_sbr_cfg->num_scf[LO]]; + pstr_tes_enc->num_mf_bands = pstr_sbr_cfg->num_master; + pstr_tes_enc->out_fs = pstr_sbr_cfg->sample_freq; + pstr_tes_enc->num_env = pstr_env_ch[ch]->str_sbr_env_frame.sbr_grid.bs_num_env; + for (idx = 0; idx < (IXHEAACE_MAX_ENV + 1); idx++) { + pstr_tes_enc->border_vec[idx] = (WORD16)pstr_const_frame_info[ch]->borders[idx]; + } + + for (idx = 0; idx < (MAXIMUM_FREQ_COEFFS + 1); idx++) { + pstr_tes_enc->f_master_tbl[idx] = (WORD16)((UWORD16)pstr_sbr_cfg->ptr_v_k_master[idx]); + } + + for (idx = 0; idx < MAXIMUM_NUM_NOISE_VALUES; idx++) { + pstr_tes_enc->inv_filt_mode[idx] = + (WORD32)pstr_env_ch[ch]->enc_env_data.sbr_invf_mode_vec[idx]; + pstr_tes_enc->invf_band_tbl[idx] = + (WORD16)pstr_env_ch[ch]->str_ton_corr.sbr_noise_floor_est.s_freq_qmf_band_tbl[idx]; + } + pstr_tes_enc->invf_band_tbl[MAXIMUM_NUM_NOISE_VALUES] = + (WORD16)pstr_env_ch[ch] + ->str_ton_corr.sbr_noise_floor_est.s_freq_qmf_band_tbl[MAXIMUM_NUM_NOISE_VALUES]; + + err_code = ixheaace_process_inter_tes(pstr_tes_enc, ptr_sbr_scratch); + if (err_code) { + return err_code; + } + + WORD32 ts, num_ts, delay; + num_ts = pstr_env_ch[ch]->str_sbr_qmf.num_time_slots; + + delay = pstr_tes_enc->op_delay + pstr_tes_enc->codec_delay + IXHEAACE_SBR_HF_ADJ_OFFSET; + + for (ts = 0; ts < delay; ts++) { + memcpy(pstr_tes_enc->qmf_buf_real[ts], pstr_tes_enc->qmf_buf_real[num_ts + ts], + IXHEAACE_QMF_CHANNELS * sizeof(pstr_tes_enc->qmf_buf_real[0][0])); + memcpy(pstr_tes_enc->qmf_buf_imag[ts], pstr_tes_enc->qmf_buf_imag[num_ts + ts], + IXHEAACE_QMF_CHANNELS * sizeof(pstr_tes_enc->qmf_buf_imag[0][0])); + } + } + } // Pitch detection, pre-processing detection and oversampling decision making if ((1 == pstr_sbr_cfg->is_esbr) && (pstr_sbr_cfg->sbr_codec == HEAAC_SBR)) { err_code = ixheaace_update_esbr_ext_data( @@ -1843,6 +2879,11 @@ IA_ERRORCODE ixheaace_extract_sbr_envelope(FLOAT32 *ptr_in_time, FLOAT32 *ptr_co if (err_code) return err_code; } + if ((pstr_sbr_cfg->sbr_codec == USAC_SBR) && (pstr_sbr_hdr->sbr_harmonic)) { + ixheaace_update_harmonic_sbr_data(transient_info, pstr_sbr_hdr->coupling, + &pstr_env_ch[0]->enc_env_data, + &pstr_env_ch[1]->enc_env_data, num_channels); + } if (num_channels == 2) { WORD32 num_bits; pstr_env_0->usac_indep_flag = pstr_sbr_bs->usac_indep_flag; @@ -1856,6 +2897,7 @@ IA_ERRORCODE ixheaace_extract_sbr_envelope(FLOAT32 *ptr_in_time, FLOAT32 *ptr_co } } else { WORD32 num_bits; + pstr_env_0->sbr_pvc_mode = pstr_sbr_hdr->sbr_pvc_mode; pstr_env_0->sbr_sinusoidal_pos_flag = 0; pstr_env_0->usac_indep_flag = pstr_sbr_bs->usac_indep_flag; @@ -1880,7 +2922,7 @@ IA_ERRORCODE ixheaace_extract_sbr_envelope(FLOAT32 *ptr_in_time, FLOAT32 *ptr_co pstr_sbr_extract_env->buffer_flag ^= 1; ch++; - } /* ch */ + } pstr_sbr_hdr->prev_coupling = pstr_sbr_hdr->coupling; diff --git a/encoder/ixheaace_sbr_env_est.h b/encoder/ixheaace_sbr_env_est.h index a53a626..ffcee6f 100644 --- a/encoder/ixheaace_sbr_env_est.h +++ b/encoder/ixheaace_sbr_env_est.h @@ -47,7 +47,8 @@ ixheaace_create_extract_sbr_envelope(WORD32 ch, ixheaace_pstr_sbr_extract_envelope pstr_sbr_ext_env, WORD32 start_index, WORD32 *ptr_common_buffer2, FLOAT32 *ptr_sbr_env_r_buf, FLOAT32 *ptr_sbr_env_i_buf, - WORD32 frame_flag_480, ixheaace_sbr_codec_type sbr_codec); + WORD32 is_ld_sbr, WORD32 frame_flag_480, + ixheaace_sbr_codec_type sbr_codec); struct ixheaace_str_sbr_config_data; struct ixheaace_str_sbr_bitstream_data; diff --git a/encoder/ixheaace_sbr_env_est_init.c b/encoder/ixheaace_sbr_env_est_init.c index 39de510..a369760 100644 --- a/encoder/ixheaace_sbr_env_est_init.c +++ b/encoder/ixheaace_sbr_env_est_init.c @@ -48,6 +48,8 @@ #include "ixheaace_common_rom.h" #include "ixheaace_sbr_ton_corr.h" +#include "iusace_esbr_pvc.h" +#include "iusace_esbr_inter_tes.h" #include "ixheaace_sbr.h" #include "ixheaace_bitbuffer.h" #include "ixheaace_sbr_cmondata.h" @@ -60,13 +62,15 @@ ixheaace_create_extract_sbr_envelope(WORD32 ch, ixheaace_pstr_sbr_extract_envelope pstr_sbr_ext_env, WORD32 start_index, WORD32 *ptr_common_buffer2, FLOAT32 *ptr_sbr_env_r_buf, FLOAT32 *ptr_sbr_env_i_buf, - WORD32 frame_flag_480, ixheaace_sbr_codec_type sbr_codec) { + WORD32 is_ld_sbr, WORD32 frame_flag_480, + ixheaace_sbr_codec_type sbr_codec) { WORD32 i; WORD32 y_buffer_length, r_buffer_length; WORD32 offset = 0; WORD32 y_buffer_write_offset = 32; WORD32 no_cols = 32; WORD32 time_slots = 16; + WORD32 sbr_ratio_idx = pstr_sbr_ext_env->sbr_ratio_idx; WORD32 qmf_time_slots = IXHEAACE_QMF_TIME_SLOTS; FLOAT32 *ptr_buffer = NULL; FLOAT32 *ptr_i_buffer = NULL; @@ -92,6 +96,15 @@ ixheaace_create_extract_sbr_envelope(WORD32 ch, y_buffer_length = y_buffer_write_offset + time_slots; r_buffer_length = time_slots; } else { + if ((sbr_codec == USAC_SBR) && (USAC_SBR_RATIO_INDEX_4_1 == sbr_ratio_idx)) { + qmf_time_slots = QMF_TIME_SLOTS_USAC_4_1; + y_buffer_write_offset = QMF_TIME_SLOTS_USAC_4_1; + } + if (is_ld_sbr && frame_flag_480) { + y_buffer_write_offset = 30; + no_cols = 30; + time_slots = 15; + } pstr_sbr_ext_env->y_buffer_write_offset = y_buffer_write_offset; y_buffer_length = pstr_sbr_ext_env->y_buffer_write_offset + y_buffer_write_offset; @@ -114,7 +127,11 @@ ixheaace_create_extract_sbr_envelope(WORD32 ch, y_buffer_length /= 2; - { pstr_sbr_ext_env->y_buffer_write_offset /= 2; } + if ((sbr_codec == USAC_SBR) && (USAC_SBR_RATIO_INDEX_4_1 == sbr_ratio_idx)) { + pstr_sbr_ext_env->y_buffer_write_offset /= 4; + } else { + pstr_sbr_ext_env->y_buffer_write_offset /= 2; + } } pstr_sbr_ext_env->buffer_flag = 0; diff --git a/encoder/ixheaace_sbr_freq_scaling.c b/encoder/ixheaace_sbr_freq_scaling.c index 61ab990..71b879c 100644 --- a/encoder/ixheaace_sbr_freq_scaling.c +++ b/encoder/ixheaace_sbr_freq_scaling.c @@ -37,6 +37,123 @@ #include "ixheaace_resampler.h" #include "ixheaace_sbr_rom.h" +static WORD32 ixheaace_get_start_freq_4_1(WORD32 fs, WORD32 start_freq) { + WORD32 minimum_k0; + const WORD32 *ptr_start_offset; + + switch (fs) { + case 16000: + minimum_k0 = 12; + break; + case 22050: + minimum_k0 = 9; + break; + case 24000: + minimum_k0 = 8; + break; + case 32000: + minimum_k0 = 8; + break; + case 44100: + minimum_k0 = 6; + break; + case 48000: + minimum_k0 = 5; + break; + default: + minimum_k0 = 5; /* illegal fs */ + } + + switch (fs) { + case 16000: { + ptr_start_offset = &ixheaace_start_freq_16k_4_1[0]; + } break; + + case 22050: { + ptr_start_offset = &ixheaace_start_freq_22k_4_1[0]; + } break; + + case 24000: { + ptr_start_offset = &ixheaace_start_freq_24k_4_1[0]; + } break; + + case 32000: { + ptr_start_offset = &ixheaace_start_freq_32k_4_1[0]; + } break; + + case 44100: + case 48000: + case 64000: { + ptr_start_offset = &ixheaace_start_freq_48k_4_1[0]; + } break; + + case 88200: + case 96000: { + ptr_start_offset = &ixheaace_start_freq_96k_4_1[0]; + } break; + + default: { + ptr_start_offset = &ixheaace_start_freq_dflt_4_1[0]; + } + } + return (minimum_k0 + ptr_start_offset[start_freq]); +} + +static WORD32 ixheaace_get_stop_freq_4_1(WORD32 fs, WORD32 stop_freq) { + WORD32 result, i; + WORD32 *v_stop_freq = 0; + WORD32 k1_min; + WORD32 v_dstop[13]; + + /* counting previous operations */ + switch (fs) { + case 16000: + k1_min = 24; + v_stop_freq = (WORD32 *)&ixheaace_stop_freq_16k_4_1[0]; + break; + case 22050: + k1_min = 17; + v_stop_freq = (WORD32 *)&ixheaace_stop_freq_22k_4_1[0]; + break; + case 24000: + k1_min = 16; + v_stop_freq = (WORD32 *)&ixheaace_stop_freq_24k_4_1[0]; + break; + case 32000: + k1_min = 16; + v_stop_freq = (WORD32 *)&ixheaace_stop_freq_32k_4_1[0]; + break; + + case 44100: + k1_min = 12; + v_stop_freq = (WORD32 *)&ixheaace_stop_freq_44k_4_1[0]; + break; + + case 48000: + k1_min = 11; + v_stop_freq = (WORD32 *)&ixheaace_stop_freq_48k_4_1[0]; + break; + + default: + v_stop_freq = (WORD32 *)&ixheaace_stop_freq_32k_4_1[0]; + k1_min = 11; /* illegal fs */ + } + + for (i = 0; i <= 12; i++) { + v_dstop[i] = v_stop_freq[i + 1] - v_stop_freq[i]; + } + + ixheaace_shellsort_int(v_dstop, 13); + + result = k1_min; + + for (i = 0; i < stop_freq; i++) { + result = result + v_dstop[i]; + } + + return result; +} + static WORD32 ixheaace_get_start_freq(WORD32 fs, WORD32 start_freq) { WORD32 minimum_k0; @@ -241,14 +358,41 @@ IA_ERRORCODE ixheaace_find_start_and_stop_band(const WORD32 sampling_freq, const WORD32 num_channels, const WORD32 start_freq, const WORD32 stop_freq, const ixheaace_sr_mode sample_rate_mode, WORD32 *ptr_k0, - WORD32 *ptr_k2) { - *ptr_k0 = ixheaace_get_start_freq(sampling_freq, start_freq); + WORD32 *ptr_k2, WORD32 sbr_ratio_idx, + ixheaace_sbr_codec_type sbr_codec) { + switch (sbr_codec) { + case USAC_SBR: { + if (sbr_ratio_idx == USAC_SBR_RATIO_INDEX_4_1) { + *ptr_k0 = ixheaace_get_start_freq_4_1(sampling_freq, start_freq); + } else { + *ptr_k0 = ixheaace_get_start_freq(sampling_freq, start_freq); + } + break; + } + default: { + *ptr_k0 = ixheaace_get_start_freq(sampling_freq, start_freq); + break; + } + } if ((sample_rate_mode == 1) && (sampling_freq * num_channels < 2 * *ptr_k0 * sampling_freq)) { return IA_EXHEAACE_INIT_FATAL_SBR_INVALID_SAMPLERATE_MODE; } if (stop_freq < 14) { - *ptr_k2 = ixheaace_get_stop_freq(sampling_freq, stop_freq); + switch (sbr_codec) { + case USAC_SBR: { + if (USAC_SBR_RATIO_INDEX_4_1 == sbr_ratio_idx) { + *ptr_k2 = ixheaace_get_stop_freq_4_1(sampling_freq, stop_freq); + } else { + *ptr_k2 = ixheaace_get_stop_freq(sampling_freq, stop_freq); + } + break; + } + default: { + *ptr_k2 = ixheaace_get_stop_freq(sampling_freq, stop_freq); + break; + } + } } else { @@ -258,8 +402,35 @@ ixheaace_find_start_and_stop_band(const WORD32 sampling_freq, const WORD32 num_c if (*ptr_k2 > num_channels) { *ptr_k2 = num_channels; } - - { + if (sbr_codec == USAC_SBR) { + if (sbr_ratio_idx == USAC_SBR_RATIO_INDEX_4_1) { + if (((*ptr_k2 - *ptr_k0) > MAXIMUM_FREQ_COEFFS_USAC) || (*ptr_k2 <= *ptr_k0)) { + return IA_EXHEAACE_INIT_FATAL_SBR_INVALID_FREQ_COEFFS; + } + if ((2 * sampling_freq == 44100) && ((*ptr_k2 - *ptr_k0) > MAXIMUM_FREQ_COEFFS_USAC)) { + return IA_EXHEAACE_INIT_FATAL_SBR_INVALID_FREQ_COEFFS; + } + if ((2 * sampling_freq >= 48000) && ((*ptr_k2 - *ptr_k0) > MAXIMUM_FREQ_COEFFS_USAC)) { + return IA_EXHEAACE_INIT_FATAL_SBR_INVALID_FREQ_COEFFS; + } + } else { + if (sampling_freq <= 32000) { + if ((*ptr_k2 - *ptr_k0) > MAXIMUM_FREQ_COEFFS_LE32KHZ) { + return IA_EXHEAACE_INIT_FATAL_SBR_INVALID_FREQ_COEFFS; + } + } else if (sampling_freq == 44100) { + if ((*ptr_k2 - *ptr_k0) > MAXIMUM_FREQ_COEFFS_EQ44KHZ) { + return IA_EXHEAACE_INIT_FATAL_SBR_INVALID_FREQ_COEFFS; + } + } else if (sampling_freq >= 48000) { + if ((*ptr_k2 - *ptr_k0) > MAXIMUM_FREQ_COEFFS_GE48KHZ) { + return IA_EXHEAACE_INIT_FATAL_SBR_INVALID_FREQ_COEFFS; + } + } else { + return IA_EXHEAACE_INIT_FATAL_SBR_INVALID_FREQ_COEFFS; + } + } + } else { if (sampling_freq <= 32000) { if ((*ptr_k2 - *ptr_k0) > MAXIMUM_FREQ_COEFFS_LE32KHZ) { return IA_EXHEAACE_INIT_FATAL_SBR_INVALID_FREQ_COEFFS; diff --git a/encoder/ixheaace_sbr_freq_scaling.h b/encoder/ixheaace_sbr_freq_scaling.h index 0ef6fcd..1a04a35 100644 --- a/encoder/ixheaace_sbr_freq_scaling.h +++ b/encoder/ixheaace_sbr_freq_scaling.h @@ -39,7 +39,8 @@ IA_ERRORCODE ixheaace_find_start_and_stop_band(const WORD32 sampling_freq, const WORD32 num_channels, const WORD32 start_freq, const WORD32 stop_freq, const ixheaace_sr_mode sample_rate_mode, WORD32 *ptr_k0, - WORD32 *ptr_k2); + WORD32 *ptr_k2, WORD32 sbr_ratio_idx, + ixheaace_sbr_codec_type sbr_codec); WORD32 ixheaace_get_sbr_start_freq_raw(WORD32 start_freq, WORD32 qmf_bands, WORD32 fs); diff --git a/encoder/ixheaace_sbr_hbe.h b/encoder/ixheaace_sbr_hbe.h index 473ed63..eae46f2 100644 --- a/encoder/ixheaace_sbr_hbe.h +++ b/encoder/ixheaace_sbr_hbe.h @@ -74,3 +74,179 @@ #define ixheaace_cbrt_calc(a) (pow(a, -0.333333f)) #define IXHEAACE_QMF_FILTER_STATE_ANA_SIZE 320 + +typedef struct { + FLOAT32 real[64][128]; + FLOAT32 imag[64][128]; +} ixheaace_str_dft_hbe_anal_coeff; + +typedef struct { + WORD32 x_over_qmf[IXHEAACE_MAX_NUM_PATCHES]; + WORD32 max_stretch; + WORD32 core_frame_length; + WORD32 hbe_qmf_in_len; + WORD32 hbe_qmf_out_len; + WORD32 no_bins; + WORD32 start_band; + WORD32 end_band; + WORD32 upsamp_4_flag; + WORD32 synth_buf_offset; + + WORD16 num_sf_bands[2]; + WORD16 *ptr_freq_band_tab[2]; + WORD16 freq_band_tbl_lo[IXHEAACE_MAX_FREQ_COEFFS / 2 + 1]; + WORD16 freq_band_tbl_hi[IXHEAACE_MAX_FREQ_COEFFS + 1]; + + FLOAT32 *ptr_input_buf; + + FLOAT32 qmf_in_buf[IXHEAACE_TWICE_QMF_SYNTH_CH_NUM][IXHEAACE_TWICE_QMF_SYNTH_CH_NUM]; + FLOAT32 qmf_out_buf[IXHEAACE_TWICE_QMF_SYNTH_CH_NUM][IXHEAACE_TWICE_QMF_SYNTH_CH_NUM]; + + WORD32 k_start; + WORD32 synth_size; + FLOAT32 synth_buf[1280]; + FLOAT32 analy_buf[640]; + FLOAT32 *ptr_syn_win_coeff; + FLOAT32 *ptr_ana_win_coeff; + + FLOAT32 *ptr_syn_cos_tab; + FLOAT32 *ptr_analy_cos_sin_tab; + + VOID (*ixheaace_real_synth_fft)(FLOAT32 *ptr_inp, FLOAT32 *ptr_out, WORD32 n_points); + FLOAT32 norm_qmf_in_buf[128][128]; + + VOID (*ixheaace_cmplx_anal_fft)(FLOAT32 *ptr_inp, FLOAT32 *ptr_out, WORD32 n_points); + + WORD32 esbr_hq; + WORD32 in_hop_size; + WORD32 fft_size[2]; + + FLOAT32 *ptr_ana_win; /* Phase Vocoder Analysis Window for FFT */ + FLOAT32 *ptr_syn_win; /* Phase Vocoder Synthesis Window for OLA */ + + FLOAT32 *ptr_spectrum; /* FFT values in cartesian space */ + FLOAT32 *ptr_spectrum_tx; /* Transposed spectrum */ + FLOAT32 *ptr_mag; /* FFT magnitudes */ + FLOAT32 *ptr_phase; /* FFT angles */ + FLOAT32 *ptr_output_buf; + WORD32 ana_fft_size[2]; /* Analysis FFT length */ + WORD32 syn_fft_size[2]; /* Synthesis FFT length */ + WORD32 out_hop_size; + WORD32 analy_size; + WORD32 x_over_bin[IXHEAACE_MAX_STRETCH][2]; + WORD32 a_start; + + FLOAT32 spectrum_buf[1536]; /* FFT values in cartesian space */ + FLOAT32 spectrum_transposed_buf[1536]; /* Transposed spectrum */ + FLOAT32 mag_buf[1536]; /* FFT magnitudes */ + FLOAT32 phase_buf[1536]; /* FFT angles */ + FLOAT32 output_buf[IXHEAACE_MAX_NUM_SAMPLES]; + FLOAT32 fd_win_buf[3][3][1536]; + + FLOAT32 analysis_window_buf[1024]; + FLOAT32 synthesis_window_buf[1024]; + + WORD32 oversampling_flag; + ixheaace_str_dft_hbe_anal_coeff str_dft_hbe_anal_coeff; + VOID (*ixheaace_hbe_anal_fft)(FLOAT32 *ptr_inp, FLOAT32 *ptr_scratch, WORD32 len, WORD32 sign); + VOID(*ixheaace_hbe_synth_ifft) + (FLOAT32 *ptr_inp, FLOAT32 *ptr_scratch, WORD32 len, WORD32 sign); + FLOAT32 *ptr_syn_cos_sin_tab; + FLOAT32 *ptr_ana_cos_sin_tab; +} ixheaace_str_esbr_hbe_txposer; + +typedef struct { + WORD16 w_16[2 * 12]; + FLOAT32 dig_rev_tab_4_16[2]; + + FLOAT32 esbr_qmf_c[1280]; + FLOAT32 esbr_qmf_c_24[480]; + FLOAT32 esbr_w_16[2 * 12]; + + FLOAT32 esbr_sin_cos_twiddle_l64[64]; + FLOAT32 esbr_alt_sin_twiddle_l64[32]; + + FLOAT32 esbr_sin_cos_twiddle_l32[32]; + FLOAT32 esbr_alt_sin_twiddle_l32[16]; + FLOAT32 esbr_t_cos_sin_l32[32 + 32]; + + FLOAT32 esbr_sin_cos_twiddle_l24[24]; + FLOAT32 esbr_alt_sin_twiddle_l24[12]; + FLOAT32 esbr_t_cos_sin_l24[24 + 24]; + + FLOAT32 esbr_sin_cos_twiddle_l16[16]; + FLOAT32 esbr_alt_sin_twiddle_l16[8]; + FLOAT32 esbr_t_cos_sin_l16[16 + 16]; +} ixheaace_str_qmf_dec_tabs_struct; + +typedef struct { + WORD32 no_channels; + WORD16 num_time_slots; + + WORD16 lsb; + WORD16 usb; + + const FLOAT32 *ptr_ana_win_coeff_32; + const FLOAT32 *ptr_esbr_cos_twiddle; + const FLOAT32 *ptr_esbr_alt_sin_twiddle; + const FLOAT32 *ptr_esbr_t_cos; + FLOAT32 anal_filter_states_32[IXHEAACE_QMF_FILTER_STATE_ANA_SIZE]; + FLOAT32 *ptr_state_new_samples_pos_low_32; + const FLOAT32 *ptr_filter_pos_32; + ixheaace_str_qmf_dec_tabs_struct *pstr_qmf_dec_tabs; +} ia_sbr_qmf_filter_bank_struct; + +typedef struct { + ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer; + VOID *ptr_hbe_txposer_buffers; + FLOAT32 ph_vocod_qmf_real[IXHEAACE_TIMESLOT_BUFFER_SIZE][IXHEAACE_NUM_QMF_SYNTH_CHANNELS]; + FLOAT32 ph_vocod_qmf_imag[IXHEAACE_TIMESLOT_BUFFER_SIZE][IXHEAACE_NUM_QMF_SYNTH_CHANNELS]; + FLOAT32 sbr_qmf_out_real[IXHEAACE_TIMESLOT_BUFFER_SIZE][IXHEAACE_NUM_QMF_SYNTH_CHANNELS]; + FLOAT32 sbr_qmf_out_imag[IXHEAACE_TIMESLOT_BUFFER_SIZE][IXHEAACE_NUM_QMF_SYNTH_CHANNELS]; + FLOAT32 qmf_buf_real[IXHEAACE_TIMESLOT_BUFFER_SIZE + 2 * 32][IXHEAACE_NUM_QMF_SYNTH_CHANNELS]; + FLOAT32 qmf_buf_imag[IXHEAACE_TIMESLOT_BUFFER_SIZE + 2 * 32][IXHEAACE_NUM_QMF_SYNTH_CHANNELS]; + + ia_sbr_qmf_filter_bank_struct str_codec_qmf_bank; +} ixheaace_str_hbe_enc; + +extern const ixheaace_str_qmf_dec_tabs_struct ixheaace_str_aac_qmf_tabs; + +VOID iusace_complex_fft_p2(FLOAT32 *ptr_x, WORD32 nlength, FLOAT32 *ptr_scratch_fft_p2_y); +VOID iusace_complex_fft_p3_no_scratch(FLOAT32 *ptr_data, WORD32 nlength); + +VOID ixheaace_esbr_hbe_data_init(ixheaace_str_esbr_hbe_txposer *pstr_esbr_hbe_txposer, + const WORD32 num_aac_samples, WORD32 samp_fac_4_flag, + const WORD32 num_out_samples, VOID *ptr_persistent_hbe_mem, + WORD32 *ptr_total_persistant); + +IA_ERRORCODE ixheaace_dft_hbe_data_reinit(ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer); + +IA_ERRORCODE ixheaace_qmf_hbe_data_reinit(ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer); + +IA_ERRORCODE ixheaace_dft_hbe_apply(ixheaace_str_esbr_hbe_txposer *pstr_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, + FLOAT32 *ptr_dft_hbe_scratch_buf); + +IA_ERRORCODE ixheaace_qmf_hbe_apply(ixheaace_str_esbr_hbe_txposer *pstr_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); + +IA_ERRORCODE ixheaace_hbe_post_anal_process(ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer, + WORD32 pitch_in_bins, WORD32 sbr_upsamp_4_flg); + +VOID ixheaace_hbe_repl_spec(WORD32 x_over_qmf[IXHEAACE_MAX_NUM_PATCHES], + FLOAT32 qmf_buf_real[][64], FLOAT32 qmf_buf_imag[][64], + WORD32 no_bins, WORD32 max_stretch); + +VOID ixheaace_esbr_qmf_init(ia_sbr_qmf_filter_bank_struct *pstr_codec_qmf_bank, + WORD32 sbr_ratio_idx, WORD32 output_frame_size); + +VOID ixheaace_esbr_analysis_filt_block( + ia_sbr_qmf_filter_bank_struct *pstr_codec_qmf_bank, + ixheaace_str_qmf_dec_tabs_struct *pstr_qmf_dec_tabs, FLOAT32 *ptr_core_coder_samples, + FLOAT32 qmf_buf_real[IXHEAACE_TIMESLOT_BUFFER_SIZE + 2 * 32][IXHEAACE_NUM_QMF_SYNTH_CHANNELS], + FLOAT32 qmf_buf_imag[IXHEAACE_TIMESLOT_BUFFER_SIZE + 2 * 32][IXHEAACE_NUM_QMF_SYNTH_CHANNELS], + WORD32 op_delay); diff --git a/encoder/ixheaace_sbr_hbe_dft_trans.c b/encoder/ixheaace_sbr_hbe_dft_trans.c index da6490f..7d107ed 100644 --- a/encoder/ixheaace_sbr_hbe_dft_trans.c +++ b/encoder/ixheaace_sbr_hbe_dft_trans.c @@ -24,6 +24,7 @@ #include "ixheaac_type_def.h" #include "ixheaace_bitbuffer.h" +#include "iusace_tns_usac.h" #include "iusace_cnst.h" #include "ixheaace_sbr_def.h" #include "ixheaace_resampler.h" @@ -33,7 +34,470 @@ #include "ixheaace_common_rom.h" #include "ixheaac_error_standards.h" #include "ixheaac_constants.h" +#include "ixheaac_esbr_rom.h" +static FLOAT32 *ixheaace_map_prot_filter(WORD32 filt_length) { + switch (filt_length) { + case 4: + return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[0]; + break; + case 8: + return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[40]; + break; + case 12: + return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[120]; + break; + case 16: + return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[240]; + break; + case 20: + return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[400]; + break; + case 24: + return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[600]; + break; + case 28: + return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff_28_36[0]; + break; + case 32: + return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[840]; + break; + case 36: + return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff_28_36[280]; + break; + case 40: + return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[1160]; + break; + case 44: + return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[1560]; + break; + default: + return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[0]; + } +} + +/** + * Calculate frequency domain window according to 23003-3:2012, 7.5.3.1 eSBR - Tool description + */ +static VOID ixheaace_create_dft_hbe_window(FLOAT32 *ptr_win, WORD32 x_over_bin1, + WORD32 x_over_bin2, WORD32 ts, WORD32 size) { + const FLOAT32 *ptr_freq_domain_win = NULL; + WORD32 n; + if (ts == 12) { + ptr_freq_domain_win = &ixheaac_dft_hbe_window_ts_12[0]; + } else { + ptr_freq_domain_win = &ixheaac_dft_hbe_window_ts_18[0]; + } + for (n = 0; n < (x_over_bin1 - ts / 2); n++) { + ptr_win[n] = 0; + } + + for (n = (x_over_bin1 - ts / 2); n <= (x_over_bin1 + ts / 2); n++) { + ptr_win[n] = (FLOAT32)ptr_freq_domain_win[n - (x_over_bin1 - ts / 2)]; + } + + for (n = (x_over_bin1 + ts / 2 + 1); n < (x_over_bin2 - ts / 2); n++) { + ptr_win[n] = (FLOAT32)1.0f; + } + + for (n = (x_over_bin2 - ts / 2); n <= (x_over_bin2 + ts / 2); n++) { + ptr_win[n] = (FLOAT32)1.0f - ptr_freq_domain_win[n - (x_over_bin2 - ts / 2)]; + } + + for (n = (x_over_bin2 + ts / 2 + 1); n < size; n++) { + ptr_win[n] = 0.0f; + } +} + +static IA_ERRORCODE ixheaace_calc_anal_synth_window(WORD32 fft_size, FLOAT32 *ptr_window) { + FLOAT32 sin_pi_2_n = 0.0f; + FLOAT32 cos_pi_2_n = 0.0f; + FLOAT32 *ptr_sin_pi_n_by_n = NULL; + WORD32 hop_stride = 1; + WORD32 i, j; + WORD32 l_fft_stride = 512; + switch (fft_size) { + case 64: + hop_stride = 16; + ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_1024[0]; + sin_pi_2_n = ptr_sin_pi_n_by_n[hop_stride >> 1]; + cos_pi_2_n = ptr_sin_pi_n_by_n[512 + (hop_stride >> 1)]; + l_fft_stride = 512; + break; + case 128: + hop_stride = 8; + ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_1024[0]; + sin_pi_2_n = ptr_sin_pi_n_by_n[hop_stride >> 1]; + cos_pi_2_n = ptr_sin_pi_n_by_n[512 + (hop_stride >> 1)]; + l_fft_stride = 512; + break; + case 256: + hop_stride = 4; + ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_1024[0]; + sin_pi_2_n = ptr_sin_pi_n_by_n[hop_stride >> 1]; + cos_pi_2_n = ptr_sin_pi_n_by_n[512 + (hop_stride >> 1)]; + l_fft_stride = 512; + break; + case 512: + hop_stride = 2; + ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_1024[0]; + sin_pi_2_n = ptr_sin_pi_n_by_n[1]; + cos_pi_2_n = ptr_sin_pi_n_by_n[512 + 1]; + l_fft_stride = 512; + break; + case 1024: + hop_stride = 1; + ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_1024[0]; + sin_pi_2_n = ixheaac_sine_pi_by_2_N[0]; + cos_pi_2_n = ixheaac_sine_pi_by_2_N[1]; + l_fft_stride = 512; + break; + case 192: + hop_stride = 4; + ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_768[0]; + sin_pi_2_n = ptr_sin_pi_n_by_n[hop_stride >> 1]; + cos_pi_2_n = ptr_sin_pi_n_by_n[384 + (hop_stride >> 1)]; + l_fft_stride = 384; + break; + case 384: + hop_stride = 2; + ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_768[0]; + sin_pi_2_n = ptr_sin_pi_n_by_n[1]; + cos_pi_2_n = ptr_sin_pi_n_by_n[384 + 1]; + l_fft_stride = 384; + break; + case 768: + hop_stride = 1; + ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_768[0]; + sin_pi_2_n = ixheaac_sine_pi_by_2_N[8]; + cos_pi_2_n = ixheaac_sine_pi_by_2_N[9]; + l_fft_stride = 384; + break; + case 320: + hop_stride = 3; + ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_960[0]; + sin_pi_2_n = ixheaac_sine_pi_by_2_N[16]; + cos_pi_2_n = ixheaac_sine_pi_by_2_N[17]; + l_fft_stride = 480; + break; + case 960: + hop_stride = 1; + ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_960[0]; + sin_pi_2_n = ixheaac_sine_pi_by_2_N[2]; + cos_pi_2_n = ixheaac_sine_pi_by_2_N[3]; + l_fft_stride = 480; + break; + case 448: + hop_stride = 2; + ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_896[0]; + sin_pi_2_n = ptr_sin_pi_n_by_n[1]; + cos_pi_2_n = ptr_sin_pi_n_by_n[448 + 1]; + l_fft_stride = 448; + break; + case 896: + hop_stride = 1; + ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_896[0]; + sin_pi_2_n = ixheaac_sine_pi_by_2_N[4]; + cos_pi_2_n = ixheaac_sine_pi_by_2_N[5]; + l_fft_stride = 448; + break; + case 576: + hop_stride = 1; + ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_576[0]; + sin_pi_2_n = ixheaac_sine_pi_by_2_N[14]; + cos_pi_2_n = ixheaac_sine_pi_by_2_N[15]; + l_fft_stride = 288; + break; + case 640: + hop_stride = 1; + ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_640[0]; + sin_pi_2_n = ixheaac_sine_pi_by_2_N[12]; + cos_pi_2_n = ixheaac_sine_pi_by_2_N[13]; + l_fft_stride = 320; + break; + case 704: + hop_stride = 1; + ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_704[0]; + sin_pi_2_n = ixheaac_sine_pi_by_2_N[10]; + cos_pi_2_n = ixheaac_sine_pi_by_2_N[11]; + l_fft_stride = 352; + break; + case 832: + hop_stride = 1; + ptr_sin_pi_n_by_n = (FLOAT32 *)&ixheaac_sine_pi_n_by_832[0]; + sin_pi_2_n = ixheaac_sine_pi_by_2_N[6]; + cos_pi_2_n = ixheaac_sine_pi_by_2_N[7]; + l_fft_stride = 416; + break; + default: + return IA_EXHEAACE_EXE_FATAL_USAC_INVALID_MAPPING; + } + + /*calculate Window*/ + for (i = 0, j = 0; j < (fft_size >> 1); i += hop_stride, j++) { + FLOAT32 cos_val = ptr_sin_pi_n_by_n[i + l_fft_stride]; + FLOAT32 sin_val = ptr_sin_pi_n_by_n[i]; + ptr_window[j] = cos_val * sin_pi_2_n + sin_val * cos_pi_2_n; + } + + for (; j < fft_size; j++, i += hop_stride) { + FLOAT32 cos_val = ptr_sin_pi_n_by_n[i - l_fft_stride]; + FLOAT32 sin_val = ptr_sin_pi_n_by_n[i]; + ptr_window[j] = sin_val * cos_pi_2_n - cos_val * sin_pi_2_n; + } + return IA_NO_ERROR; +} + +VOID ixheaace_esbr_hbe_data_init(ixheaace_str_esbr_hbe_txposer *pstr_esbr_hbe_txposer, + const WORD32 num_aac_samples, WORD32 samp_fac_4_flag, + const WORD32 num_out_samples, VOID *ptr_persistent_hbe_mem, + WORD32 *ptr_total_persistant) { + WORD32 used_persistent = 0; + + if (pstr_esbr_hbe_txposer) { + memset(pstr_esbr_hbe_txposer, 0, sizeof(ixheaace_str_esbr_hbe_txposer)); + + pstr_esbr_hbe_txposer->core_frame_length = num_aac_samples; + + pstr_esbr_hbe_txposer->no_bins = num_out_samples / IXHEAACE_NUM_QMF_SYNTH_CHANNELS; + + pstr_esbr_hbe_txposer->hbe_qmf_in_len = pstr_esbr_hbe_txposer->no_bins; + + pstr_esbr_hbe_txposer->hbe_qmf_out_len = 2 * pstr_esbr_hbe_txposer->hbe_qmf_in_len; + + pstr_esbr_hbe_txposer->ptr_input_buf = (FLOAT32 *)ptr_persistent_hbe_mem; + used_persistent += (num_aac_samples + IXHEAACE_NUM_QMF_SYNTH_CHANNELS) * + sizeof(pstr_esbr_hbe_txposer->ptr_input_buf[0]); + + pstr_esbr_hbe_txposer->upsamp_4_flag = samp_fac_4_flag; + + if (pstr_esbr_hbe_txposer) { + pstr_esbr_hbe_txposer->fft_size[0] = num_aac_samples; + pstr_esbr_hbe_txposer->fft_size[1] = (int)(IXHEAACE_FD_OVERSAMPLING_FAC * num_aac_samples); + + /* + Worst Case Memory requirements for DFT based HBE. + analysis ptr_win = num_aac_samples * sizeof(float) = 1024 * sizeof(FLOAT32) + synthesis ptr_win = num_aac_samples * sizeof(float) = 1024 * sizeof(FLOAT32) + ptr_spectrum = num_aac_samples * sizeof(float) * 1.5 = 1536 * sizeof(FLOAT32) + spectrumTransposed = num_aac_samples * sizeof(float) = 1536 * sizeof(FLOAT32) + ptr_mag = 1536 * sizeof(FLOAT32) + ptr_phase = 1536 * sizeof(FLOAT32) + pstr_esbr_hbe_txposer->inBuf = 2048 * sizeof(FLOAT32) + pstr_esbr_hbe_txposer->outBuf = 4096 * sizeof(FLOAT32) + fd_win_buf = 2560 * 3 * sizeof(FLOAT32) + Total ~ (1024 * 2 + 1536 * 4 + 2048 * 1 + 4096 * 1 + 2560 * 3) * sizeof(FLOAT32) + = 22016 * sizeof(FLOAT32) + */ + + pstr_esbr_hbe_txposer->ptr_spectrum = &pstr_esbr_hbe_txposer->spectrum_buf[0]; + pstr_esbr_hbe_txposer->ptr_spectrum_tx = &pstr_esbr_hbe_txposer->spectrum_transposed_buf[0]; + pstr_esbr_hbe_txposer->ptr_mag = &pstr_esbr_hbe_txposer->mag_buf[0]; + pstr_esbr_hbe_txposer->ptr_phase = &pstr_esbr_hbe_txposer->phase_buf[0]; + pstr_esbr_hbe_txposer->ptr_output_buf = &pstr_esbr_hbe_txposer->output_buf[0]; + } + } + *ptr_total_persistant = used_persistent; +} + +IA_ERRORCODE ixheaace_dft_hbe_data_reinit(ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer) { + WORD32 sfb; + WORD32 patch; + WORD32 i; + WORD32 temp_start; + FLOAT32 fb_ratio; + WORD32 stop_patch; + WORD32 in_hop_size_divisor = 8; + static const WORD32 trans_samp[2] = {12, 18}; /* FD transition samples */ + WORD32 err = IA_NO_ERROR; + + pstr_hbe_txposer->start_band = pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_LOW][0]; + pstr_hbe_txposer->end_band = + pstr_hbe_txposer + ->ptr_freq_band_tab[IXHEAACE_LOW][pstr_hbe_txposer->num_sf_bands[IXHEAACE_LOW]]; + pstr_hbe_txposer->esbr_hq = 1; + + pstr_hbe_txposer->synth_size = 4 * ((pstr_hbe_txposer->start_band + 4) / 8 + 1); + pstr_hbe_txposer->k_start = ixheaac_start_subband2kL_tbl[pstr_hbe_txposer->start_band]; + + fb_ratio = pstr_hbe_txposer->synth_size / 32.0f; + + pstr_hbe_txposer->ana_fft_size[0] = (WORD32)(fb_ratio * pstr_hbe_txposer->fft_size[0]); + pstr_hbe_txposer->ana_fft_size[1] = (WORD32)(fb_ratio * pstr_hbe_txposer->fft_size[1]); + + pstr_hbe_txposer->in_hop_size = pstr_hbe_txposer->ana_fft_size[0] / in_hop_size_divisor; + + pstr_hbe_txposer->ptr_syn_win = (FLOAT32 *)&pstr_hbe_txposer->synthesis_window_buf[0]; + pstr_hbe_txposer->ptr_ana_win = (FLOAT32 *)&pstr_hbe_txposer->analysis_window_buf[0]; + + err = ixheaace_calc_anal_synth_window(pstr_hbe_txposer->ana_fft_size[0], + pstr_hbe_txposer->ptr_ana_win); + if (err) { + return err; + } + + memset(pstr_hbe_txposer->synth_buf, 0, sizeof(pstr_hbe_txposer->synth_buf)); + + pstr_hbe_txposer->ptr_syn_win_coeff = ixheaace_map_prot_filter(pstr_hbe_txposer->synth_size); + + temp_start = 2 * ((pstr_hbe_txposer->start_band - 1) / 2); /* Largest start band */ + pstr_hbe_txposer->analy_size = + 4 * ((min(64, pstr_hbe_txposer->end_band + 1) - temp_start - 1) / 4 + + 1); /* Quantize in steps of 4 */ + pstr_hbe_txposer->a_start = temp_start - max(0, temp_start + pstr_hbe_txposer->analy_size - 64); + + fb_ratio = pstr_hbe_txposer->analy_size / 64.0f; + + pstr_hbe_txposer->syn_fft_size[0] = (WORD32)(fb_ratio * pstr_hbe_txposer->fft_size[0]); + pstr_hbe_txposer->syn_fft_size[1] = (WORD32)(fb_ratio * pstr_hbe_txposer->fft_size[1]); + + pstr_hbe_txposer->out_hop_size = 2 * pstr_hbe_txposer->syn_fft_size[0] / in_hop_size_divisor; + + err = ixheaace_calc_anal_synth_window(pstr_hbe_txposer->syn_fft_size[0], + pstr_hbe_txposer->ptr_syn_win); + if (err) { + return err; + } + + pstr_hbe_txposer->ptr_ana_win_coeff = ixheaace_map_prot_filter(pstr_hbe_txposer->analy_size); + + /* calculation of x_over_bin array and x_over_qmf array */ + + memset(&pstr_hbe_txposer->x_over_qmf[0], 0, sizeof(pstr_hbe_txposer->x_over_qmf)); + + for (i = 0; i < IXHEAACE_MAX_STRETCH; i++) { + memset(&pstr_hbe_txposer->x_over_bin[i][0], 0, + 2 * sizeof(pstr_hbe_txposer->x_over_bin[i][0])); + } + sfb = 0; + stop_patch = IXHEAACE_MAX_STRETCH; + + switch (pstr_hbe_txposer->synth_size) { + case 4: + pstr_hbe_txposer->ptr_syn_cos_tab = (FLOAT32 *)ixheaac_synth_cos_table_kl_4; + pstr_hbe_txposer->ixheaace_real_synth_fft = &ixheaac_real_synth_fft_p2; + break; + case 8: + pstr_hbe_txposer->ptr_syn_cos_tab = (FLOAT32 *)ixheaac_synth_cos_table_kl_8; + pstr_hbe_txposer->ixheaace_real_synth_fft = &ixheaac_real_synth_fft_p2; + break; + case 12: + pstr_hbe_txposer->ptr_syn_cos_tab = (FLOAT32 *)ixheaac_synth_cos_table_kl_12; + pstr_hbe_txposer->ixheaace_real_synth_fft = &ixheaac_real_synth_fft_p3; + break; + case 16: + pstr_hbe_txposer->ptr_syn_cos_tab = (FLOAT32 *)ixheaac_synth_cos_table_kl_16; + pstr_hbe_txposer->ixheaace_real_synth_fft = &ixheaac_real_synth_fft_p2; + break; + case 20: + pstr_hbe_txposer->ptr_syn_cos_tab = (FLOAT32 *)ixheaac_synth_cos_table_kl_20; + break; + case 28: + pstr_hbe_txposer->ptr_syn_cos_tab = (FLOAT32 *)ixheaac_synth_cos_table_kl_20; + break; + default: + pstr_hbe_txposer->ptr_syn_cos_tab = (FLOAT32 *)ixheaac_synth_cos_table_kl_4; + pstr_hbe_txposer->ixheaace_real_synth_fft = &ixheaac_real_synth_fft_p2; + } + + { + WORD32 l, k, L = pstr_hbe_txposer->analy_size; + for (k = 0; k < L; k++) { + for (l = 0; l < 2 * L; l++) { + pstr_hbe_txposer->str_dft_hbe_anal_coeff.real[k][l] = + (FLOAT32)cos(PI / (2 * L) * + ((k + 0.5) * (2 * l - L / 64.0) - L / 64.0 * pstr_hbe_txposer->a_start)); + pstr_hbe_txposer->str_dft_hbe_anal_coeff.imag[k][l] = + (FLOAT32)sin(PI / (2 * L) * + ((k + 0.5) * (2 * l - L / 64.0) - L / 64.0 * pstr_hbe_txposer->a_start)); + } + } + } + + for (patch = 1; patch <= stop_patch; patch++) { + while (sfb <= pstr_hbe_txposer->num_sf_bands[IXHEAACE_LOW] && + pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_LOW][sfb] <= + patch * pstr_hbe_txposer->start_band) + sfb++; + if (sfb <= pstr_hbe_txposer->num_sf_bands[IXHEAACE_LOW]) { + /* If the distance is larger than three QMF bands - try aligning to high resolution + * frequency bands instead. */ + if ((patch * pstr_hbe_txposer->start_band - + pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_LOW][sfb - 1]) <= 3) { + pstr_hbe_txposer->x_over_qmf[patch - 1] = + pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_LOW][sfb - 1]; + if (patch <= IXHEAACE_MAX_STRETCH) { + pstr_hbe_txposer->x_over_bin[patch - 1][0] = + (WORD32)(pstr_hbe_txposer->fft_size[0] * + pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_LOW][sfb - 1] / 128 + + 0.5); + pstr_hbe_txposer->x_over_bin[patch - 1][1] = + (WORD32)(pstr_hbe_txposer->fft_size[1] * + pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_LOW][sfb - 1] / 128 + + 0.5); + } + } else { + WORD32 sfb_idx = 0; + while (sfb_idx <= pstr_hbe_txposer->num_sf_bands[IXHEAACE_HIGH] && + pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_HIGH][sfb_idx] <= + patch * pstr_hbe_txposer->start_band) + sfb_idx++; + pstr_hbe_txposer->x_over_qmf[patch - 1] = + pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_HIGH][sfb_idx - 1]; + if (patch <= IXHEAACE_MAX_STRETCH) { + pstr_hbe_txposer->x_over_bin[patch - 1][0] = + (WORD32)(pstr_hbe_txposer->fft_size[0] * + pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_HIGH][sfb_idx - 1] / 128 + + 0.5); + pstr_hbe_txposer->x_over_bin[patch - 1][1] = + (WORD32)(pstr_hbe_txposer->fft_size[1] * + pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_HIGH][sfb_idx - 1] / 128 + + 0.5); + } + } + } else { + pstr_hbe_txposer->x_over_qmf[patch - 1] = pstr_hbe_txposer->end_band; + if (patch <= IXHEAACE_MAX_STRETCH) { + pstr_hbe_txposer->x_over_bin[patch - 1][0] = + (WORD32)(pstr_hbe_txposer->fft_size[0] * pstr_hbe_txposer->end_band / 128 + 0.5); + pstr_hbe_txposer->x_over_bin[patch - 1][1] = + (WORD32)(pstr_hbe_txposer->fft_size[1] * pstr_hbe_txposer->end_band / 128 + 0.5); + } + pstr_hbe_txposer->max_stretch = min(patch, IXHEAACE_MAX_STRETCH); + break; + } + } + + /* calculation of frequency domain windows */ + for (patch = 0; patch < pstr_hbe_txposer->max_stretch - 1; patch++) { + for (i = 0; i < 2; i++) { + ixheaace_create_dft_hbe_window(pstr_hbe_txposer->fd_win_buf[patch][i], + pstr_hbe_txposer->x_over_bin[patch][i], + pstr_hbe_txposer->x_over_bin[patch + 1][i], trans_samp[i], + pstr_hbe_txposer->fft_size[i]); + } + } + return err; +} + +static VOID ixheaace_dft_hbe_apply_win(const FLOAT32 *ptr_x, const FLOAT32 *ptr_y, FLOAT32 *ptr_z, + WORD32 n) { + WORD32 i; + for (i = 0; i < n; i++) { + ptr_z[i] = ptr_x[i] * ptr_y[i]; + } +} + +VOID ixheaace_dft_hbe_fft_memmove(FLOAT32 *ptr_spectrum, WORD32 size) { + WORD32 n = 0; + + while (n < size / 2) { + FLOAT32 tmp = ptr_spectrum[n]; + ptr_spectrum[n] = ptr_spectrum[n + size / 2]; + ptr_spectrum[n + size / 2] = tmp; + n++; + } +} VOID ixheaace_karth2polar(FLOAT32 *ptr_spectrum, FLOAT32 *ptr_mag, FLOAT32 *ptr_phase, WORD32 fft_size) { WORD32 n; @@ -60,3 +524,484 @@ VOID ixheaace_karth2polar(FLOAT32 *ptr_spectrum, FLOAT32 *ptr_mag, FLOAT32 *ptr_ ptr_mag[fft_size / 2] = ptr_spectrum[1]; } } +VOID ixheaace_hbe_fft_tab(ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer) { + WORD32 oversampling_flag = pstr_hbe_txposer->oversampling_flag; + WORD32 ana_fft_size = pstr_hbe_txposer->ana_fft_size[oversampling_flag]; + WORD32 syn_fft_size = pstr_hbe_txposer->syn_fft_size[oversampling_flag]; + + switch (ana_fft_size) { + case 576: + pstr_hbe_txposer->ptr_ana_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_576; + break; + case 384: + pstr_hbe_txposer->ptr_ana_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_384; + break; + case 512: + pstr_hbe_txposer->ptr_ana_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_512; + break; + case 768: + pstr_hbe_txposer->ptr_ana_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_768; + break; + default: + break; + } + + switch (syn_fft_size) { + case 448: + pstr_hbe_txposer->ptr_syn_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_448; + break; + case 512: + pstr_hbe_txposer->ptr_syn_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_512; + break; + case 768: + pstr_hbe_txposer->ptr_syn_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_768; + break; + case 672: + pstr_hbe_txposer->ptr_syn_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_672; + break; + default: + break; + } +} + +IA_ERRORCODE ixheaace_hbe_fft_map(ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer) { + WORD32 oversampling_flag = pstr_hbe_txposer->oversampling_flag; + WORD32 ana_fft_size = pstr_hbe_txposer->ana_fft_size[oversampling_flag]; + WORD32 syn_fft_size = pstr_hbe_txposer->syn_fft_size[oversampling_flag]; + + switch (ana_fft_size) { + case 576: + pstr_hbe_txposer->ptr_ana_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_576; + pstr_hbe_txposer->ixheaace_hbe_anal_fft = &ixheaace_hbe_apply_fft_288; + break; + case 384: + pstr_hbe_txposer->ptr_ana_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_384; + pstr_hbe_txposer->ixheaace_hbe_anal_fft = &ixheaace_hbe_apply_cfftn_gen; + break; + case 512: + pstr_hbe_txposer->ptr_ana_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_512; + pstr_hbe_txposer->ixheaace_hbe_anal_fft = &ixheaace_hbe_apply_cfftn; + break; + case 768: + pstr_hbe_txposer->ptr_ana_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_768; + pstr_hbe_txposer->ixheaace_hbe_anal_fft = &ixheaace_hbe_apply_cfftn_gen; + break; + default: + return IA_EXHEAACE_EXE_FATAL_USAC_INVALID_MAPPING; + break; + } + + switch (syn_fft_size) { + case 448: + pstr_hbe_txposer->ptr_syn_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_448; + pstr_hbe_txposer->ixheaace_hbe_synth_ifft = &ixheaace_hbe_apply_ifft_224; + break; + case 512: + pstr_hbe_txposer->ptr_syn_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_512; + pstr_hbe_txposer->ixheaace_hbe_synth_ifft = &ixheaace_hbe_apply_cfftn; + break; + case 576: + pstr_hbe_txposer->ptr_syn_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_576; + pstr_hbe_txposer->ixheaace_hbe_synth_ifft = &ixheaace_hbe_apply_fft_288; + break; + case 768: + pstr_hbe_txposer->ptr_syn_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_768; + pstr_hbe_txposer->ixheaace_hbe_synth_ifft = &ixheaace_hbe_apply_cfftn_gen; + break; + case 672: + pstr_hbe_txposer->ptr_syn_cos_sin_tab = (FLOAT32 *)ixheaac_sin_cos_672; + pstr_hbe_txposer->ixheaace_hbe_synth_ifft = &ixheaace_hbe_apply_ifft_336; + break; + default: + return IA_EXHEAACE_EXE_FATAL_USAC_INVALID_MAPPING; + break; + } + + return IA_NO_ERROR; +} + +VOID ia_dft_hbe_apply_polar_t2(WORD32 T, ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer, + WORD32 pitch_in_bins, WORD out_transform_size) { + WORD32 tr; + WORD32 ti; + WORD32 m_tr = 0; + WORD32 p, i; + FLOAT32 mag_t; + FLOAT32 phase_t; + FLOAT32 m_val; + FLOAT32(*fd_win_buf)[3][3][1536] = &pstr_hbe_txposer->fd_win_buf; + FLOAT32 *ptr_phase = pstr_hbe_txposer->ptr_phase; + WORD32 oversampling_flag = pstr_hbe_txposer->oversampling_flag; + WORD32 fft_size = pstr_hbe_txposer->fft_size[oversampling_flag]; + FLOAT32 *ptr_spectrum_tx = pstr_hbe_txposer->ptr_spectrum_tx; + FLOAT32 *ptr_mag = pstr_hbe_txposer->ptr_mag; + /* pitch_in_bins is given with the resolution of a 1536 point FFT */ + FLOAT32 p_flt = fft_size * pitch_in_bins / 1536.0f; + p = (WORD32)p_flt; + FLOAT32 q_thr = 4.0f; + + if (T < 2) { + // To avoid invalid access by fd_win_buf + T = 2; + } + i = 0; + while (i <= out_transform_size) { + WORD32 utk = i; + + mag_t = (*fd_win_buf)[T - 2][oversampling_flag][i] * ptr_mag[utk]; + + phase_t = T * ptr_phase[utk]; + + if (phase_t == 0.0) { + ptr_spectrum_tx[2 * i] += mag_t; + } else { + ptr_spectrum_tx[2 * i] += mag_t * (FLOAT32)cos(phase_t); + ptr_spectrum_tx[2 * i + 1] += mag_t * (FLOAT32)sin(phase_t); + } + if (p > 0) { + m_val = 0; + for (tr = 1; tr < T; tr++) { + FLOAT32 temp; + ti = (WORD32)((2.0f * i - tr * p_flt) / T + 0.5f); + if ((ti < 0) || (ti + p > fft_size / 2)) continue; + temp = min(ptr_mag[ti], ptr_mag[ti + p]); + if (temp > m_val) { + m_val = temp; + m_tr = tr; + utk = ti; + } + } /* for tr */ + + if (m_val > q_thr * ptr_mag[2 * i / T]) { + mag_t = (*fd_win_buf)[T - 2][oversampling_flag][i] * ((FLOAT32)sqrt(ptr_mag[utk])) * + ((FLOAT32)sqrt(ptr_mag[utk + p])); + phase_t = ((FLOAT32)(T - m_tr)) * ptr_phase[utk] + ((FLOAT32)m_tr) * ptr_phase[utk + p]; + ptr_spectrum_tx[2 * i] += mag_t * ((FLOAT32)cos(phase_t)); + ptr_spectrum_tx[2 * i + 1] += mag_t * ((FLOAT32)sin(phase_t)); + } + } + i++; + } +} + +VOID ia_dft_hbe_apply_polar_t_3(WORD32 T, ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer, + WORD32 pitch_in_bins, WORD out_transform_size) { + WORD32 tr; + WORD32 ti; + WORD32 m_tr = 0; + WORD32 p, i; + FLOAT32 mag_t = 0.0f; + FLOAT32 phase_t; + FLOAT32 m_val; + FLOAT32(*fd_win_buf)[3][3][1536] = &pstr_hbe_txposer->fd_win_buf; + FLOAT32 *ptr_phase = pstr_hbe_txposer->ptr_phase; + WORD32 oversampling_flag = pstr_hbe_txposer->oversampling_flag; + WORD32 fft_size = pstr_hbe_txposer->fft_size[oversampling_flag]; + FLOAT32 *ptr_spectrum_tx = pstr_hbe_txposer->ptr_spectrum_tx; + FLOAT32 *ptr_mag = pstr_hbe_txposer->ptr_mag; + /* pitch_in_bins is given with the resolution of a 1536 point FFT */ + FLOAT32 p_flt = fft_size * pitch_in_bins / 1536.0f; + p = (WORD32)p_flt; + FLOAT32 q_thr = 4.0f; + + if (T < 3) { + // To avoid invalid access by fd_win_buf + T = 3; + } + + i = 0; + while (i <= out_transform_size) { + WORD32 utk = 2 * i / T; + FLOAT32 ptk = (2.0f * i / T) - utk; + FLOAT32 k; + + if (i % 3 == 0) { + mag_t = (*fd_win_buf)[T - 2][oversampling_flag][i] * ptr_mag[utk]; + } else if (i % 3 == 1) { + k = (FLOAT32)cbrt(ptr_mag[utk]); + mag_t = + (*fd_win_buf)[T - 2][oversampling_flag][i] * k * (FLOAT32)pow(ptr_mag[utk + 1], ptk); + } else if (i % 3 == 2) { + k = (FLOAT32)cbrt(ptr_mag[utk + 1]); + mag_t = + (*fd_win_buf)[T - 2][oversampling_flag][i] * (FLOAT32)pow(ptr_mag[utk], 1.0 - ptk) * k; + } + + phase_t = T * ((1 - ptk) * ptr_phase[utk] + ptk * ptr_phase[utk + 1]); + + ptr_spectrum_tx[2 * i] += mag_t * (FLOAT32)cos(phase_t); + ptr_spectrum_tx[2 * i + 1] += mag_t * (FLOAT32)sin(phase_t); + + if (p > 0) { + m_val = 0; + for (tr = 1; tr < T; tr++) { + FLOAT32 temp; + ti = (WORD32)((2.0f * i - tr * p_flt) / T + 0.5f); + if ((ti < 0) || (ti + p > fft_size / 2)) continue; + temp = min(ptr_mag[ti], ptr_mag[ti + p]); + if (temp > m_val) { + m_val = temp; + m_tr = tr; + utk = ti; + } + } /* for tr */ + + if (m_val > q_thr * ptr_mag[2 * i / T]) { + FLOAT32 r = (FLOAT32)m_tr / T; + switch (m_tr) { + case 1: + k = (FLOAT32)(cbrt((FLOAT32)ptr_mag[utk + p])); + mag_t = (*fd_win_buf)[T - 2][oversampling_flag][i] * + (FLOAT32)pow(ptr_mag[utk], 1.0 - r) * k; + phase_t = (T - m_tr) * ptr_phase[utk] + ptr_phase[utk + p]; + break; + + case 2: + k = (FLOAT32)(cbrt((FLOAT32)ptr_mag[utk])); + mag_t = (*fd_win_buf)[T - 2][oversampling_flag][i] * k * + (FLOAT32)pow(ptr_mag[utk + p], r); + phase_t = ptr_phase[utk] + m_tr * ptr_phase[utk + p]; + break; + } + + ptr_spectrum_tx[2 * i] += mag_t * (FLOAT32)cos(phase_t); + ptr_spectrum_tx[2 * i + 1] += mag_t * (FLOAT32)sin(phase_t); + } + } + i++; + } +} + +VOID ia_dft_hbe_apply_polar_t(WORD32 T, ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer, + WORD32 pitch_in_bins, WORD out_transform_size) { + WORD32 tr; + WORD32 ti; + WORD32 m_tr = 0; + WORD32 p, i; + FLOAT32 mag_t; + FLOAT32 phase_t; + FLOAT32 m_val; + FLOAT32(*fd_win_buf)[3][3][1536] = &pstr_hbe_txposer->fd_win_buf; + FLOAT32 *ptr_phase = pstr_hbe_txposer->ptr_phase; + WORD32 oversampling_flag = pstr_hbe_txposer->oversampling_flag; + WORD32 fft_size = pstr_hbe_txposer->fft_size[oversampling_flag]; + FLOAT32 *ptr_spectrum_tx = pstr_hbe_txposer->ptr_spectrum_tx; + FLOAT32 *ptr_mag = pstr_hbe_txposer->ptr_mag; + /* pitch_in_bins is given with the resolution of a 1536 point FFT */ + FLOAT32 p_flt = fft_size * pitch_in_bins / 1536.0f; + p = (WORD32)p_flt; + FLOAT32 q_thr = 4.0f; + + if (T < 2) { + // To avoid invalid access by fd_win_buf + T = 2; + } + for (i = 0; i <= out_transform_size; i++) { + WORD32 utk = 2 * i / T; + FLOAT32 ptk = (2.0f * i / T) - utk; + + mag_t = (*fd_win_buf)[T - 2][oversampling_flag][i] * (FLOAT32)pow(ptr_mag[utk], 1.0f - ptk) * + (FLOAT32)pow(ptr_mag[utk + 1], ptk); + + phase_t = T * ((1 - ptk) * ptr_phase[utk] + ptk * ptr_phase[utk + 1]); + + ptr_spectrum_tx[2 * i] += mag_t * (FLOAT32)cos(phase_t); + ptr_spectrum_tx[2 * i + 1] += mag_t * (FLOAT32)sin(phase_t); + + if (p > 0) { + m_val = 0; + for (tr = 1; tr < T; tr++) { + FLOAT32 temp; + ti = (WORD32)((2.0f * i - tr * p_flt) / T + 0.5f); + if ((ti < 0) || (ti + p > fft_size / 2)) continue; + temp = min(ptr_mag[ti], ptr_mag[ti + p]); + if (temp > m_val) { + m_val = temp; + m_tr = tr; + utk = ti; + } + } /* for tr */ + + if (m_val > q_thr * ptr_mag[2 * i / T]) { + FLOAT32 r = (FLOAT32)m_tr / T; + mag_t = (*fd_win_buf)[T - 2][oversampling_flag][i] * (FLOAT32)pow(ptr_mag[utk], 1.0 - r) * + (FLOAT32)pow(ptr_mag[utk + p], r); + phase_t = (T - m_tr) * ptr_phase[utk] + m_tr * ptr_phase[utk + p]; + ptr_spectrum_tx[2 * i] += mag_t * (FLOAT32)cos(phase_t); + ptr_spectrum_tx[2 * i + 1] += mag_t * (FLOAT32)sin(phase_t); + } + } + } +} + +IA_ERRORCODE ixheaace_dft_hbe_apply(ixheaace_str_esbr_hbe_txposer *pstr_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, + FLOAT32 *ptr_dft_hbe_scratch_buf) { + WORD32 in_offset = 0; + WORD32 out_offset = 0; + WORD32 in_hop_size = pstr_hbe_txposer->in_hop_size; + WORD32 oversampling_flag = pstr_hbe_txposer->oversampling_flag; + WORD32 fft_size = pstr_hbe_txposer->fft_size[oversampling_flag]; + + WORD32 out_hop_size = pstr_hbe_txposer->out_hop_size; + WORD32 num_in_samples = num_columns * pstr_hbe_txposer->synth_size; + WORD32 ana_fft_size = pstr_hbe_txposer->ana_fft_size[oversampling_flag]; + WORD32 syn_fft_size = pstr_hbe_txposer->syn_fft_size[oversampling_flag]; + + WORD32 ana_pad_size = (ana_fft_size - pstr_hbe_txposer->ana_fft_size[0]) / 2; + WORD32 syn_pad_size = (syn_fft_size - pstr_hbe_txposer->syn_fft_size[0]) / 2; + + FLOAT32 *ptr_input_buf = pstr_hbe_txposer->ptr_input_buf; + FLOAT32 *ptr_output_buf = pstr_hbe_txposer->ptr_output_buf; + FLOAT32 *ptr_spectrum = pstr_hbe_txposer->ptr_spectrum; + FLOAT32 *ptr_spectrum_tx = pstr_hbe_txposer->ptr_spectrum_tx; + FLOAT32 *ptr_mag = pstr_hbe_txposer->ptr_mag; + FLOAT32 *ptr_phase = pstr_hbe_txposer->ptr_phase; + WORD32 i, T; + FLOAT32 *ptr_cos_fft; + FLOAT32 *ptr_cos_ifft; + + WORD32 ana_fft_offset = pstr_hbe_txposer->k_start * fft_size / 32; + WORD32 syn_fft_offset = pstr_hbe_txposer->a_start * fft_size / 64; + /* pitch_in_bins is given with the resolution of a 1536 point FFT */ + WORD32 err_code = IA_NO_ERROR; + + memcpy(pstr_hbe_txposer->ptr_input_buf, + pstr_hbe_txposer->ptr_input_buf + pstr_hbe_txposer->ana_fft_size[0], + pstr_hbe_txposer->ana_fft_size[0] * sizeof(pstr_hbe_txposer->ptr_input_buf[0])); + + err_code = ixheaace_real_synth_filt(pstr_hbe_txposer, num_columns, qmf_buf_real, qmf_buf_imag); + if (err_code) { + return err_code; + } + + memcpy(ptr_output_buf, ptr_output_buf + 2 * pstr_hbe_txposer->syn_fft_size[0], + 2 * pstr_hbe_txposer->syn_fft_size[0] * sizeof(ptr_output_buf[0])); + + memset(ptr_output_buf + 2 * pstr_hbe_txposer->syn_fft_size[0], 0, + 2 * pstr_hbe_txposer->syn_fft_size[0] * sizeof(ptr_output_buf[0])); + + err_code = ixheaace_hbe_fft_map(pstr_hbe_txposer); + if (err_code) { + return err_code; + } + + while (in_offset < num_in_samples) { + memset(ptr_spectrum, 0, fft_size * sizeof(ptr_spectrum[0])); + memset(ptr_spectrum_tx, 0, ((fft_size + 2) * sizeof(ptr_spectrum_tx[0]))); + + memset(ptr_mag, 0, (fft_size / 2 + 2) * sizeof(ptr_mag[0])); + memset(ptr_phase, 0, (fft_size / 2 + 2) * sizeof(ptr_phase[0])); + ixheaace_dft_hbe_apply_win(ptr_input_buf + in_offset, pstr_hbe_txposer->ptr_ana_win, + ptr_spectrum + ana_pad_size + ana_fft_offset, + pstr_hbe_txposer->ana_fft_size[0]); + ixheaace_dft_hbe_fft_memmove(ptr_spectrum + ana_fft_offset, ana_fft_size); + { + WORD32 len = ana_fft_size; + ptr_cos_fft = pstr_hbe_txposer->ptr_ana_cos_sin_tab; + FLOAT32 *ptr_fft_data = ptr_spectrum + ana_fft_offset; + FLOAT32 tmp1, tmp2, tmp3, tmp4; + (*(pstr_hbe_txposer->ixheaace_hbe_anal_fft))(ptr_fft_data, ptr_dft_hbe_scratch_buf, len / 2, + -1); + tmp1 = ptr_fft_data[0] + ptr_fft_data[1]; + ptr_fft_data[1] = ptr_fft_data[0] - ptr_fft_data[1]; + ptr_fft_data[0] = tmp1; + + i = 1; + while (i <= (len / 4 + (len % 4) / 2)) { + tmp1 = ptr_fft_data[2 * i] - ptr_fft_data[len - 2 * i]; + tmp2 = ptr_fft_data[2 * i + 1] + ptr_fft_data[len - 2 * i + 1]; + + tmp3 = (*(ptr_cos_fft)) * tmp1 - (*(ptr_cos_fft + 1)) * tmp2; + tmp4 = (*(ptr_cos_fft + 1)) * tmp1 + (*(ptr_cos_fft)) * tmp2; + + ptr_cos_fft = ptr_cos_fft + 2; + + tmp1 = ptr_fft_data[2 * i] + ptr_fft_data[len - 2 * i]; + tmp2 = ptr_fft_data[2 * i + 1] - ptr_fft_data[len - 2 * i + 1]; + + ptr_fft_data[2 * i + 0] = 0.5f * (tmp1 - tmp3); + ptr_fft_data[2 * i + 1] = 0.5f * (tmp2 - tmp4); + ptr_fft_data[len - 2 * i + 0] = 0.5f * (tmp1 + tmp3); + ptr_fft_data[len - 2 * i + 1] = -0.5f * (tmp2 + tmp4); + ++i; + } + } + ixheaace_karth2polar(ptr_spectrum + ana_fft_offset, ptr_mag + ana_fft_offset / 2, + ptr_phase + ana_fft_offset / 2, ana_fft_size); + + for (T = 2; T <= pstr_hbe_txposer->max_stretch; T++) { + /* max_stretch cannot be greater than 4. So, T can be 2 to 4*/ + + WORD32 out_transform_size; + + /* 0ptr_syn_cos_sin_tab; + FLOAT32 *ptr_fft_data = ptr_spectrum_tx + syn_fft_offset; + FLOAT32 tmp1, tmp2, tmp3, tmp4; + + FLOAT32 scale = 1.0f / len; + tmp1 = ptr_fft_data[0] + ptr_fft_data[1]; + ptr_fft_data[1] = scale * (ptr_fft_data[0] - ptr_fft_data[1]); + ptr_fft_data[0] = scale * tmp1; + + for (i = 1; i <= (len / 4 + (len % 4) / 2); ++i) { + tmp1 = ptr_fft_data[2 * i] - ptr_fft_data[len - 2 * i]; + tmp2 = ptr_fft_data[2 * i + 1] + ptr_fft_data[len - 2 * i + 1]; + + tmp3 = (*(ptr_cos_ifft)) * tmp1 + (*(ptr_cos_ifft + 1)) * tmp2; + tmp4 = -(*(ptr_cos_ifft + 1)) * tmp1 + (*(ptr_cos_ifft)) * tmp2; + + ptr_cos_ifft = ptr_cos_ifft + 2; + + tmp1 = ptr_fft_data[2 * i] + ptr_fft_data[len - 2 * i]; + tmp2 = ptr_fft_data[2 * i + 1] - ptr_fft_data[len - 2 * i + 1]; + + ptr_fft_data[2 * i] = scale * (tmp1 - tmp3); + ptr_fft_data[2 * i + 1] = scale * (tmp2 - tmp4); + ptr_fft_data[len - 2 * i] = scale * (tmp1 + tmp3); + ptr_fft_data[len - 2 * i + 1] = -scale * (tmp2 + tmp4); + } + + (*(pstr_hbe_txposer->ixheaace_hbe_synth_ifft))(ptr_fft_data, ptr_dft_hbe_scratch_buf, + len / 2, 1); + } + + ixheaace_dft_hbe_fft_memmove(ptr_spectrum_tx + syn_fft_offset, syn_fft_size); + ixheaace_dft_hbe_apply_win( + ptr_spectrum_tx + syn_pad_size + syn_fft_offset, pstr_hbe_txposer->ptr_syn_win, + ptr_spectrum_tx + syn_pad_size + syn_fft_offset, pstr_hbe_txposer->syn_fft_size[0]); + + for (i = 0; i < pstr_hbe_txposer->syn_fft_size[0]; i++) { + ptr_output_buf[out_offset + i] += ptr_spectrum_tx[syn_pad_size + syn_fft_offset + i]; + } + + in_offset += in_hop_size; + out_offset += out_hop_size; + + } /* while(in_offset +#include +#include "ixheaac_constants.h" +#include "ixheaace_constants.h" +#include "iusace_basic_ops_flt.h" +#include "ixheaace_common_utils.h" +#include "ixheaac_fft_ifft_rom.h" +#include "ixheaac_basic_ops32.h" +#include "ixheaac_basic_ops40.h" +#include "ixheaac_basic_ops.h" + +#define DIG_REV(i, m, j) \ + do { \ + unsigned _ = (i); \ + _ = ((_ & 0x33333333) << 2) | ((_ & ~0x33333333) >> 2); \ + _ = ((_ & 0x0F0F0F0F) << 4) | ((_ & ~0x0F0F0F0F) >> 4); \ + _ = ((_ & 0x00FF00FF) << 8) | ((_ & ~0x00FF00FF) >> 8); \ + (j) = _ >> (m); \ + } while (0) + +#define CPLX_MPY_FFT(re, im, a, b, c, d) \ + do { \ + re = ((a * c) - (b * d)); \ + im = ((a * d) + (b * c)); \ + } while (0) + +#define CPLX_MPY_IFFT(re, im, a, b, c, d) \ + do { \ + re = ((a * c) + (b * d)); \ + im = (-(a * d) + (b * c)); \ + } while (0) + +VOID ixheaace_hbe_apply_ifft_7(FLOAT32 *ptr_inp, FLOAT32 *ptr_op) { + FLOAT32 x0r, x1r, x2r, x3r, x4r, x5r, x6r, x7r, x8r; + FLOAT32 x0i, x1i, x2i, x3i, x4i, x5i, x6i, x7i, x8i; + FLOAT32 y0r, y1r, y2r, y3r, y4r, y5r, y6r, y7r, y8r; + FLOAT32 y0i, y1i, y2i, y3i, y4i, y5i, y6i, y7i, y8i; + + /* + * Node 1 of Winograd FFT for 7 point + * + * 1 0 0 0 0 0 0 + * 0 1 0 0 0 0 1 + * 0 1 0 0 0 0 -1 + * 0 0 1 0 0 1 0 + * 0 0 1 0 0 -1 0 + * 0 0 0 1 1 0 0 + * 0 0 0 -1 1 0 0 + * + */ + + x0r = ptr_inp[0]; + x0i = ptr_inp[1]; + x1r = ptr_inp[2] + ptr_inp[12]; + x1i = ptr_inp[3] + ptr_inp[13]; + x2r = ptr_inp[2] - ptr_inp[12]; + x2i = ptr_inp[3] - ptr_inp[13]; + x3r = ptr_inp[4] + ptr_inp[10]; + x3i = ptr_inp[5] + ptr_inp[11]; + x4r = ptr_inp[4] - ptr_inp[10]; + x4i = ptr_inp[5] - ptr_inp[11]; + x5r = ptr_inp[8] + ptr_inp[6]; + x5i = ptr_inp[9] + ptr_inp[7]; + x6r = ptr_inp[8] - ptr_inp[6]; + x6i = ptr_inp[9] - ptr_inp[7]; + + /* + * Node 2 of Winograd FFT for 7 point + * + * 1 0 0 0 0 0 0 + * 0 1 0 1 0 1 0 + * 0 1 0 -1 0 0 0 + * 0 -1 0 0 0 1 0 + * 0 0 0 1 0 -1 0 + * 0 0 1 0 1 0 1 + * 0 0 1 0 -1 0 0 + * 0 0 -1 0 0 0 1 + * 0 0 0 0 1 0 -1 + * + */ + + y0r = x0r; + y0i = x0i; + y1r = x1r + x3r + x5r; + y1i = x1i + x3i + x5i; + y2r = x1r - x3r; + y2i = x1i - x3i; + y3r = x5r - x1r; + y3i = x5i - x1i; + y4r = x3r - x5r; + y4i = x3i - x5i; + y5r = x2r + x4r + x6r; + y5i = x2i + x4i + x6i; + y6r = x2r - x4r; + y6i = x2i - x4i; + y7r = x6r - x2r; + y7i = x6i - x2i; + y8r = x4r - x6r; + y8i = x4i - x6i; + + /* + * Node 3 of Winograd FFT for 7 point + * + * 1 1 0 0 0 0 0 0 0 + * 1 c70 0 0 0 0 0 0 0 + * 0 0 c71 0 0 0 0 0 0 + * 0 0 0 c72 0 0 0 0 0 + * 0 0 0 0 c73 0 0 0 0 + * 0 0 0 0 0 jc74 0 0 0 + * 0 0 0 0 0 0 jc75 0 0 + * 0 0 0 0 0 0 0 jc76 0 + * 0 0 0 0 0 0 0 0 jc77 + * + */ + x0r = y0r + y1r; + x0i = y0i + y1i; + x1r = y0r + C70 * y1r; + x1i = y0i + C70 * y1i; + x2r = C71 * y2r; + x2i = C71 * y2i; + x3r = C72 * y3r; + x3i = C72 * y3i; + x4r = C73 * y4r; + x4i = C73 * y4i; + x5r = C74 * y5i; + x5i = -C74 * y5r; + x6r = C75 * y6i; + x6i = -C75 * y6r; + x7r = C76 * y7i; + x7i = -C76 * y7r; + x8r = C77 * y8i; + x8i = -C77 * y8r; + + /* + * Node 4 of Winograd FFT for 7 point + * + * 1 0 0 0 0 0 0 0 0 + * 0 1 1 0 1 0 0 0 0 + * 0 1 -1 -1 0 0 0 0 0 + * 0 1 0 1 -1 0 0 0 0 + * 0 0 0 0 0 1 1 0 1 + * 0 0 0 0 0 1 -1 -1 0 + * 0 0 0 0 0 1 0 1 -1 + * + */ + + y0r = x0r; + y0i = x0i; + y1r = x1r + x2r + x4r; + y1i = x1i + x2i + x4i; + y2r = x1r - x2r - x3r; + y2i = x1i - x2i - x3i; + y3r = x1r + x3r - x4r; + y3i = x1i + x3i - x4i; + y4r = x5r + x6r + x8r; + y4i = x5i + x6i + x8i; + y5r = x5r - x6r - x7r; + y5i = x5i - x6i - x7i; + y6r = x5r + x7r - x8r; + y6i = x5i + x7i - x8i; + + /* + * Node 5 of Winograd FFT for 7 point + * + * 1 0 0 0 0 0 0 + * 0 1 0 0 1 0 0 + * 0 0 0 1 0 0 1 + * 0 0 1 0 0 -1 0 + * 0 0 1 0 0 1 0 + * 0 0 0 1 0 0 -1 + * 0 1 0 0 -1 0 0 + * + */ + x0r = y0r; + x0i = y0i; + x1r = y1r + y4r; + x1i = y1i + y4i; + x2r = y3r + y6r; + x2i = y3i + y6i; + x3r = y2r - y5r; + x3i = y2i - y5i; + x4r = y2r + y5r; + x4i = y2i + y5i; + x5r = y3r - y6r; + x5i = y3i - y6i; + x6r = y1r - y4r; + x6i = y1i - y4i; + + ptr_op[0] = x0r; + ptr_op[1] = x0i; + ptr_op[2] = x1r; + ptr_op[3] = x1i; + ptr_op[4] = x2r; + ptr_op[5] = x2i; + ptr_op[6] = x3r; + ptr_op[7] = x3i; + ptr_op[8] = x4r; + ptr_op[9] = x4i; + ptr_op[10] = x5r; + ptr_op[11] = x5i; + ptr_op[12] = x6r; + ptr_op[13] = x6i; +} + +VOID ixheaace_hbe_apply_fft_3(FLOAT32 *ptr_inp, FLOAT32 *ptr_op, WORD32 i_sign) { + FLOAT32 add_r, sub_r; + FLOAT32 add_i, sub_i; + FLOAT32 x_01_r, x_01_i, temp; + + FLOAT32 p1, p2, p3, p4; + + /* mu = PI / 3; The cos and sin values are in Q31 + cosmu is 0.5 so used >> 1 instead of multiplication */ + + FLOAT64 sinmu; + sinmu = -0.866025403784439 * (FLOAT64)i_sign; + + x_01_r = ptr_inp[0] + ptr_inp[2]; + x_01_i = ptr_inp[1] + ptr_inp[3]; + + add_r = ptr_inp[2] + ptr_inp[4]; + add_i = ptr_inp[3] + ptr_inp[5]; + + sub_r = ptr_inp[2] - ptr_inp[4]; + sub_i = ptr_inp[3] - ptr_inp[5]; + + p1 = add_r / (FLOAT32)2.0; + p4 = add_i / (FLOAT32)2.0; + p2 = (FLOAT32)((FLOAT64)sub_i * sinmu); + p3 = (FLOAT32)((FLOAT64)sub_r * sinmu); + + temp = ptr_inp[0] - p1; + + ptr_op[0] = x_01_r + ptr_inp[4]; + ptr_op[1] = x_01_i + ptr_inp[5]; + ptr_op[2] = temp + p2; + ptr_op[3] = (ptr_inp[1] - p3) - p4; + ptr_op[4] = temp - p2; + ptr_op[5] = (ptr_inp[1] + p3) - p4; +} + +VOID ixheaace_hbe_apply_tw_mult_ifft(FLOAT32 *ptr_inp, FLOAT32 *ptr_op, WORD32 dim1, WORD32 dim2, + const FLOAT32 *ptr_tw) { + FLOAT32 accu1, accu2; + WORD32 i, j; + WORD32 step_val = (dim2 - 1) << 1; + for (i = 0; i < (dim2); i++) { + ptr_op[0] = ptr_inp[0]; + ptr_op[1] = ptr_inp[1]; + ptr_op += 2; + ptr_inp += 2; + } + + for (j = 0; j < (dim1 - 1); j++) { + ptr_op[0] = ptr_inp[0]; + ptr_op[1] = ptr_inp[1]; + ptr_inp += 2; + ptr_op += 2; + for (i = 0; i < (dim2 - 1); i++) { + CPLX_MPY_IFFT(accu1, accu2, ptr_inp[2 * i + 0], ptr_inp[2 * i + 1], ptr_tw[2 * i + 1], + ptr_tw[2 * i]); + ptr_op[2 * i + 0] = accu1; + ptr_op[2 * i + 1] = accu2; + } + ptr_inp += step_val; + ptr_op += step_val; + ptr_tw += (dim2 - 1) * 2; + } +} + +VOID ixheaace_hbe_apply_tw_mult_fft(FLOAT32 *ptr_inp, FLOAT32 *ptr_op, WORD32 dim1, WORD32 dim2, + const FLOAT32 *ptr_tw) { + FLOAT32 accu1, accu2; + WORD32 i, j; + WORD32 step_val = (dim2 - 1) << 1; + for (i = 0; i < (dim2); i++) { + ptr_op[0] = ptr_inp[0]; + ptr_op[1] = ptr_inp[1]; + ptr_op += 2; + ptr_inp += 2; + } + + for (j = 0; j < (dim1 - 1); j++) { + ptr_op[0] = ptr_inp[0]; + ptr_op[1] = ptr_inp[1]; + ptr_inp += 2; + ptr_op += 2; + for (i = 0; i < (dim2 - 1); i++) { + CPLX_MPY_FFT(accu1, accu2, ptr_inp[2 * i + 0], ptr_inp[2 * i + 1], ptr_tw[2 * i + 1], + ptr_tw[2 * i]); + ptr_op[2 * i + 0] = accu1; + ptr_op[2 * i + 1] = accu2; + } + ptr_inp += step_val; + ptr_op += step_val; + ptr_tw += (dim2 - 1) * 2; + } +} + +VOID ixheaace_hbe_apply_cfftn(FLOAT32 re[], FLOAT32 *ptr_scratch, WORD32 n_pass, WORD32 i_sign) { + WORD32 i, j, k, n_stages, h2; + FLOAT32 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + WORD32 del, nodespacing, in_loop_cnt; + WORD32 not_power_4; + WORD32 dig_rev_shift; + WORD32 mpass = n_pass; + WORD32 npoints = n_pass; + const FLOAT64 *ptr_w; + FLOAT32 *ptr_x = ptr_scratch; + FLOAT32 *y = ptr_scratch + (2 * n_pass); + FLOAT32 *ptr_y = y; + + dig_rev_shift = ixheaac_norm32(mpass) + 1 - 16; + n_stages = 30 - ixheaac_norm32(mpass); /* log2(npoints), if npoints=2^m */ + not_power_4 = n_stages & 1; + + n_stages = n_stages >> 1; + + ptr_w = ixheaac_twid_tbl_fft_double; + ptr_x = re; + + dig_rev_shift = MAX(dig_rev_shift, 0); + + if (i_sign == -1) { + for (i = 0; i < npoints; i += 4) { + FLOAT32 *ptr_inp = ptr_x; + FLOAT32 tmk; + + DIG_REV(i, dig_rev_shift, h2); + if (not_power_4) { + h2 += 1; + h2 &= ~1; + } + ptr_inp += (h2); + + x0r = *ptr_inp; + x0i = *(ptr_inp + 1); + ptr_inp += (npoints >> 1); + + x1r = *ptr_inp; + x1i = *(ptr_inp + 1); + ptr_inp += (npoints >> 1); + + x2r = *ptr_inp; + x2i = *(ptr_inp + 1); + ptr_inp += (npoints >> 1); + + x3r = *ptr_inp; + x3i = *(ptr_inp + 1); + + x0r = x0r + x2r; + x0i = x0i + x2i; + + tmk = x0r - x2r; + x2r = tmk - x2r; + tmk = x0i - x2i; + x2i = tmk - x2i; + + x1r = x1r + x3r; + x1i = x1i + x3i; + + tmk = x1r - x3r; + x3r = tmk - x3r; + tmk = x1i - x3i; + x3i = tmk - x3i; + + x0r = x0r + x1r; + x0i = x0i + x1i; + + tmk = x0r - x1r; + x1r = tmk - x1r; + tmk = x0i - x1i; + x1i = tmk - x1i; + + x2r = x2r + x3i; + x2i = x2i - x3r; + + tmk = x2r - x3i; + x3i = tmk - x3i; + tmk = x2i + x3r; + x3r = tmk + x3r; + + *ptr_y++ = x0r; + *ptr_y++ = x0i; + *ptr_y++ = x2r; + *ptr_y++ = x2i; + *ptr_y++ = x1r; + *ptr_y++ = x1i; + *ptr_y++ = x3i; + *ptr_y++ = x3r; + } + ptr_y -= 2 * npoints; + del = 4; + nodespacing = 64; + in_loop_cnt = npoints >> 4; + for (i = n_stages - 1; i > 0; i--) { + const FLOAT64 *ptr_twiddle = ptr_w; + FLOAT32 *data = ptr_y; + FLOAT64 w_1, w_2, w_3, w_4, w_5, w_6; + WORD32 sec_loop_cnt; + + for (k = in_loop_cnt; k != 0; k--) { + x0r = (*data); + x0i = (*(data + 1)); + data += ((SIZE_T)del << 1); + + x1r = (*data); + x1i = (*(data + 1)); + data += ((SIZE_T)del << 1); + + x2r = (*data); + x2i = (*(data + 1)); + data += ((SIZE_T)del << 1); + + x3r = (*data); + x3i = (*(data + 1)); + data -= 3 * (del << 1); + + x0r = x0r + x2r; + x0i = x0i + x2i; + x2r = x0r - (x2r * 2); + x2i = x0i - (x2i * 2); + x1r = x1r + x3r; + x1i = x1i + x3i; + x3r = x1r - (x3r * 2); + x3i = x1i - (x3i * 2); + + x0r = x0r + x1r; + x0i = x0i + x1i; + x1r = x0r - (x1r * 2); + x1i = x0i - (x1i * 2); + x2r = x2r + x3i; + x2i = x2i - x3r; + x3i = x2r - (x3i * 2); + x3r = x2i + (x3r * 2); + + *data = x0r; + *(data + 1) = x0i; + data += ((SIZE_T)del << 1); + + *data = x2r; + *(data + 1) = x2i; + data += ((SIZE_T)del << 1); + + *data = x1r; + *(data + 1) = x1i; + data += ((SIZE_T)del << 1); + + *data = x3i; + *(data + 1) = x3r; + data += ((SIZE_T)del << 1); + } + data = ptr_y + 2; + + sec_loop_cnt = (nodespacing * del); + sec_loop_cnt = (sec_loop_cnt / 4) + (sec_loop_cnt / 8) - (sec_loop_cnt / 16) + + (sec_loop_cnt / 32) - (sec_loop_cnt / 64) + (sec_loop_cnt / 128) - + (sec_loop_cnt / 256); + + for (j = nodespacing; j <= sec_loop_cnt; j += nodespacing) { + w_1 = *(ptr_twiddle + j); + w_4 = *(ptr_twiddle + j + 257); + w_2 = *(ptr_twiddle + ((SIZE_T)j << 1)); + w_5 = *(ptr_twiddle + ((SIZE_T)j << 1) + 257); + w_3 = *(ptr_twiddle + j + ((SIZE_T)j << 1)); + w_6 = *(ptr_twiddle + j + ((SIZE_T)j << 1) + 257); + + for (k = in_loop_cnt; k != 0; k--) { + FLOAT32 tmp; + FLOAT32 x0r1, x0i1, x1r1, x1i1, x2r1, x2i1, x3r1, x3i1; + /*x0 is loaded later to avoid register crunch*/ + + data += ((SIZE_T)del << 1); + + x1r1 = *data; + x1i1 = *(data + 1); + data += ((SIZE_T)del << 1); + + x2r1 = *data; + x2i1 = *(data + 1); + data += ((SIZE_T)del << 1); + + x3r1 = *data; + x3i1 = *(data + 1); + data -= 3 * (del << 1); + + tmp = + (FLOAT32)(ixheaace_dmult((FLOAT64)x1r1, w_1) - ixheaace_dmult((FLOAT64)x1i1, w_4)); + x1i1 = (FLOAT32)ixheaace_dmac(ixheaace_dmult((FLOAT64)x1r1, w_4), (FLOAT64)x1i1, w_1); + x1r1 = tmp; + + tmp = + (FLOAT32)(ixheaace_dmult((FLOAT64)x2r1, w_2) - ixheaace_dmult((FLOAT64)x2i1, w_5)); + x2i1 = (FLOAT32)ixheaace_dmac(ixheaace_dmult((FLOAT64)x2r1, w_5), (FLOAT64)x2i1, w_2); + x2r1 = tmp; + + tmp = + (FLOAT32)(ixheaace_dmult((FLOAT64)x3r1, w_3) - ixheaace_dmult((FLOAT64)x3i1, w_6)); + x3i1 = (FLOAT32)ixheaace_dmac(ixheaace_dmult((FLOAT64)x3r1, w_6), (FLOAT64)x3i1, w_3); + x3r1 = tmp; + + x0r1 = (*data); + x0i1 = (*(data + 1)); + + x0r1 = x0r1 + (x2r1); + x0i1 = x0i1 + (x2i1); + x2r1 = x0r1 - (x2r1 * 2); + x2i1 = x0i1 - (x2i1 * 2); + x1r1 = x1r1 + x3r1; + x1i1 = x1i1 + x3i1; + x3r1 = x1r1 - (x3r1 * 2); + x3i1 = x1i1 - (x3i1 * 2); + + x0r1 = x0r1 + (x1r1); + x0i1 = x0i1 + (x1i1); + x1r1 = x0r1 - (x1r1 * 2); + x1i1 = x0i1 - (x1i1 * 2); + x2r1 = x2r1 + (x3i1); + x2i1 = x2i1 - (x3r1); + x3i1 = x2r1 - (x3i1 * 2); + x3r1 = x2i1 + (x3r1 * 2); + + *data = x0r1; + *(data + 1) = x0i1; + data += ((SIZE_T)del << 1); + + *data = x2r1; + *(data + 1) = x2i1; + data += ((SIZE_T)del << 1); + + *data = x1r1; + *(data + 1) = x1i1; + data += ((SIZE_T)del << 1); + + *data = x3i1; + *(data + 1) = x3r1; + data += ((SIZE_T)del << 1); + } + data -= 2 * npoints; + data += 2; + } + for (; j <= (nodespacing * del) >> 1; j += nodespacing) { + w_1 = *(ptr_twiddle + j); + w_4 = *(ptr_twiddle + j + 257); + w_2 = *(ptr_twiddle + ((SIZE_T)j << 1)); + w_5 = *(ptr_twiddle + ((SIZE_T)j << 1) + 257); + w_3 = *(ptr_twiddle + j + ((SIZE_T)j << 1) - 256); + w_6 = *(ptr_twiddle + j + ((SIZE_T)j << 1) + 1); + + for (k = in_loop_cnt; k != 0; k--) { + FLOAT32 tmp; + FLOAT32 x0r1, x0i1, x1r1, x1i1, x2r1, x2i1, x3r1, x3i1; + /*x0 is loaded later to avoid register crunch*/ + + data += ((SIZE_T)del << 1); + + x1r1 = *data; + x1i1 = *(data + 1); + data += ((SIZE_T)del << 1); + + x2r1 = *data; + x2i1 = *(data + 1); + data += ((SIZE_T)del << 1); + + x3r1 = *data; + x3i1 = *(data + 1); + data -= 3 * (del << 1); + + tmp = + (FLOAT32)(ixheaace_dmult((FLOAT64)x1r1, w_1) - ixheaace_dmult((FLOAT64)x1i1, w_4)); + x1i1 = (FLOAT32)ixheaace_dmac(ixheaace_dmult((FLOAT64)x1r1, w_4), (FLOAT64)x1i1, w_1); + x1r1 = tmp; + + tmp = + (FLOAT32)(ixheaace_dmult((FLOAT64)x2r1, w_2) - ixheaace_dmult((FLOAT64)x2i1, w_5)); + x2i1 = (FLOAT32)ixheaace_dmac(ixheaace_dmult((FLOAT64)x2r1, w_5), (FLOAT64)x2i1, w_2); + x2r1 = tmp; + + tmp = + (FLOAT32)(ixheaace_dmult((FLOAT64)x3r1, w_6) + ixheaace_dmult((FLOAT64)x3i1, w_3)); + x3i1 = + (FLOAT32)(-ixheaace_dmult((FLOAT64)x3r1, w_3) + ixheaace_dmult((FLOAT64)x3i1, w_6)); + x3r1 = tmp; + + x0r1 = (*data); + x0i1 = (*(data + 1)); + + x0r1 = x0r1 + (x2r1); + x0i1 = x0i1 + (x2i1); + x2r1 = x0r1 - (x2r1 * 2); + x2i1 = x0i1 - (x2i1 * 2); + x1r1 = x1r1 + x3r1; + x1i1 = x1i1 + x3i1; + x3r1 = x1r1 - (x3r1 * 2); + x3i1 = x1i1 - (x3i1 * 2); + + x0r1 = x0r1 + (x1r1); + x0i1 = x0i1 + (x1i1); + x1r1 = x0r1 - (x1r1 * 2); + x1i1 = x0i1 - (x1i1 * 2); + x2r1 = x2r1 + (x3i1); + x2i1 = x2i1 - (x3r1); + x3i1 = x2r1 - (x3i1 * 2); + x3r1 = x2i1 + (x3r1 * 2); + + *data = x0r1; + *(data + 1) = x0i1; + data += ((SIZE_T)del << 1); + + *data = x2r1; + *(data + 1) = x2i1; + data += ((SIZE_T)del << 1); + + *data = x1r1; + *(data + 1) = x1i1; + data += ((SIZE_T)del << 1); + + *data = x3i1; + *(data + 1) = x3r1; + data += ((SIZE_T)del << 1); + } + data -= 2 * npoints; + data += 2; + } + for (; j <= sec_loop_cnt * 2; j += nodespacing) { + w_1 = *(ptr_twiddle + j); + w_4 = *(ptr_twiddle + j + 257); + w_2 = *(ptr_twiddle + ((SIZE_T)j << 1) - 256); + w_5 = *(ptr_twiddle + ((SIZE_T)j << 1) + 1); + w_3 = *(ptr_twiddle + j + ((SIZE_T)j << 1) - 256); + w_6 = *(ptr_twiddle + j + ((SIZE_T)j << 1) + 1); + + for (k = in_loop_cnt; k != 0; k--) { + FLOAT32 tmp; + FLOAT32 x0r1, x0i1, x1r1, x1i1, x2r1, x2i1, x3r1, x3i1; + /*x0 is loaded later to avoid register crunch*/ + + data += ((SIZE_T)del << 1); + + x1r1 = *data; + x1i1 = *(data + 1); + data += ((SIZE_T)del << 1); + + x2r1 = *data; + x2i1 = *(data + 1); + data += ((SIZE_T)del << 1); + + x3r1 = *data; + x3i1 = *(data + 1); + data -= 3 * (del << 1); + + tmp = + (FLOAT32)(ixheaace_dmult((FLOAT64)x1r1, w_1) - ixheaace_dmult((FLOAT64)x1i1, w_4)); + x1i1 = (FLOAT32)ixheaace_dmac(ixheaace_dmult(x1r1, w_4), x1i1, w_1); + x1r1 = tmp; + + tmp = + (FLOAT32)(ixheaace_dmult((FLOAT64)x2r1, w_5) + ixheaace_dmult((FLOAT64)x2i1, w_2)); + x2i1 = (FLOAT32)(-ixheaace_dmult(x2r1, w_2) + ixheaace_dmult(x2i1, w_5)); + x2r1 = tmp; + + tmp = + (FLOAT32)(ixheaace_dmult((FLOAT64)x3r1, w_6) + ixheaace_dmult((FLOAT64)x3i1, w_3)); + x3i1 = + (FLOAT32)(-ixheaace_dmult((FLOAT64)x3r1, w_3) + ixheaace_dmult((FLOAT64)x3i1, w_6)); + x3r1 = tmp; + + x0r1 = (*data); + x0i1 = (*(data + 1)); + + x0r1 = x0r1 + (x2r1); + x0i1 = x0i1 + (x2i1); + x2r1 = x0r1 - (x2r1 * 2); + x2i1 = x0i1 - (x2i1 * 2); + x1r1 = x1r1 + x3r1; + x1i1 = x1i1 + x3i1; + x3r1 = x1r1 - (x3r1 * 2); + x3i1 = x1i1 - (x3i1 * 2); + + x0r1 = x0r1 + (x1r1); + x0i1 = x0i1 + (x1i1); + x1r1 = x0r1 - (x1r1 * 2); + x1i1 = x0i1 - (x1i1 * 2); + x2r1 = x2r1 + (x3i1); + x2i1 = x2i1 - (x3r1); + x3i1 = x2r1 - (x3i1 * 2); + x3r1 = x2i1 + (x3r1 * 2); + + *data = x0r1; + *(data + 1) = x0i1; + data += ((SIZE_T)del << 1); + + *data = x2r1; + *(data + 1) = x2i1; + data += ((SIZE_T)del << 1); + + *data = x1r1; + *(data + 1) = x1i1; + data += ((SIZE_T)del << 1); + + *data = x3i1; + *(data + 1) = x3r1; + data += ((SIZE_T)del << 1); + } + data -= 2 * npoints; + data += 2; + } + for (; j < nodespacing * del; j += nodespacing) { + w_1 = *(ptr_twiddle + j); + w_4 = *(ptr_twiddle + j + 257); + w_2 = *(ptr_twiddle + ((SIZE_T)j << 1) - 256); + w_5 = *(ptr_twiddle + ((SIZE_T)j << 1) + 1); + w_3 = *(ptr_twiddle + j + ((SIZE_T)j << 1) - 512); + w_6 = *(ptr_twiddle + j + ((SIZE_T)j << 1) - 512 + 257); + + for (k = in_loop_cnt; k != 0; k--) { + FLOAT32 tmp; + FLOAT32 x0r1, x0i1, x1r1, x1i1, x2r1, x2i1, x3r1, x3i1; + /*x0 is loaded later to avoid register crunch*/ + + data += ((SIZE_T)del << 1); + + x1r1 = *data; + x1i1 = *(data + 1); + data += ((SIZE_T)del << 1); + + x2r1 = *data; + x2i1 = *(data + 1); + data += ((SIZE_T)del << 1); + + x3r1 = *data; + x3i1 = *(data + 1); + data -= 3 * (del << 1); + + tmp = + (FLOAT32)(ixheaace_dmult((FLOAT64)x1r1, w_1) - ixheaace_dmult((FLOAT64)x1i1, w_4)); + x1i1 = (FLOAT32)ixheaace_dmac(ixheaace_dmult((FLOAT64)x1r1, w_4), (FLOAT64)x1i1, w_1); + x1r1 = tmp; + + tmp = + (FLOAT32)(ixheaace_dmult((FLOAT64)x2r1, w_5) + ixheaace_dmult((FLOAT64)x2i1, w_2)); + x2i1 = + (FLOAT32)(-ixheaace_dmult((FLOAT64)x2r1, w_2) + ixheaace_dmult((FLOAT64)x2i1, w_5)); + x2r1 = tmp; + + tmp = + (FLOAT32)(-ixheaace_dmult((FLOAT64)x3r1, w_3) + ixheaace_dmult((FLOAT64)x3i1, w_6)); + x3i1 = (FLOAT32)ixheaace_dmac(ixheaace_dmult((FLOAT64)x3r1, w_6), (FLOAT64)x3i1, w_3); + x3r1 = tmp; + + x0r1 = (*data); + x0i1 = (*(data + 1)); + + x0r1 = x0r1 + (x2r1); + x0i1 = x0i1 + (x2i1); + x2r1 = x0r1 - (x2r1 * 2); + x2i1 = x0i1 - (x2i1 * 2); + x1r1 = x1r1 + x3r1; + x1i1 = x1i1 - x3i1; + x3r1 = x1r1 - (x3r1 * 2); + x3i1 = x1i1 + (x3i1 * 2); + + x0r1 = x0r1 + (x1r1); + x0i1 = x0i1 + (x1i1); + x1r1 = x0r1 - (x1r1 * 2); + x1i1 = x0i1 - (x1i1 * 2); + x2r1 = x2r1 + (x3i1); + x2i1 = x2i1 - (x3r1); + x3i1 = x2r1 - (x3i1 * 2); + x3r1 = x2i1 + (x3r1 * 2); + + *data = x0r1; + *(data + 1) = x0i1; + data += ((SIZE_T)del << 1); + + *data = x2r1; + *(data + 1) = x2i1; + data += ((SIZE_T)del << 1); + + *data = x1r1; + *(data + 1) = x1i1; + data += ((SIZE_T)del << 1); + + *data = x3i1; + *(data + 1) = x3r1; + data += ((SIZE_T)del << 1); + } + data -= 2 * npoints; + data += 2; + } + nodespacing >>= 2; + del <<= 2; + in_loop_cnt >>= 2; + } + if (not_power_4) { + const double *ptr_twiddle = ptr_w; + nodespacing <<= 1; + + for (j = del / 2; j != 0; j--) { + FLOAT64 w_1 = *ptr_twiddle; + FLOAT64 w_4 = *(ptr_twiddle + 257); + FLOAT32 tmp; + ptr_twiddle += nodespacing; + + x0r = *ptr_y; + x0i = *(ptr_y + 1); + ptr_y += ((SIZE_T)del << 1); + + x1r = *ptr_y; + x1i = *(ptr_y + 1); + + tmp = (FLOAT32)(ixheaace_dmult((FLOAT64)x1r, w_1) - ixheaace_dmult((FLOAT64)x1i, w_4)); + x1i = (FLOAT32)ixheaace_dmac(ixheaace_dmult((FLOAT64)x1r, w_4), (FLOAT64)x1i, w_1); + x1r = tmp; + + *ptr_y = (x0r) - (x1r); + *(ptr_y + 1) = (x0i) - (x1i); + ptr_y -= ((SIZE_T)del << 1); + + *ptr_y = (x0r) + (x1r); + *(ptr_y + 1) = (x0i) + (x1i); + ptr_y += 2; + } + ptr_twiddle = ptr_w; + for (j = del / 2; j != 0; j--) { + FLOAT64 w_1 = *ptr_twiddle; + FLOAT64 w_4 = *(ptr_twiddle + 257); + FLOAT32 tmp; + ptr_twiddle += nodespacing; + + x0r = *ptr_y; + x0i = *(ptr_y + 1); + ptr_y += ((SIZE_T)del << 1); + + x1r = *ptr_y; + x1i = *(ptr_y + 1); + + tmp = (FLOAT32)(ixheaace_dmult((FLOAT64)x1r, w_4) + ixheaace_dmult((FLOAT64)x1i, w_1)); + x1i = (FLOAT32)(-ixheaace_dmult((FLOAT64)x1r, w_1) + ixheaace_dmult((FLOAT64)x1i, w_4)); + x1r = tmp; + + *ptr_y = (x0r) - (x1r); + *(ptr_y + 1) = (x0i) - (x1i); + ptr_y -= ((SIZE_T)del << 1); + + *ptr_y = (x0r) + (x1r); + *(ptr_y + 1) = (x0i) + (x1i); + ptr_y += 2; + } + } + } + + /**********************IFFT******************************************/ + + else { + for (i = 0; i < npoints; i += 4) { + FLOAT32 *ptr_inp = ptr_x; + + DIG_REV(i, dig_rev_shift, h2); + if (not_power_4) { + h2 += 1; + h2 &= ~1; + } + ptr_inp += (h2); + + x0r = *ptr_inp; + x0i = *(ptr_inp + 1); + ptr_inp += (npoints >> 1); + + x1r = *ptr_inp; + x1i = *(ptr_inp + 1); + ptr_inp += (npoints >> 1); + + x2r = *ptr_inp; + x2i = *(ptr_inp + 1); + ptr_inp += (npoints >> 1); + + x3r = *ptr_inp; + x3i = *(ptr_inp + 1); + + x0r = x0r + x2r; + x0i = x0i + x2i; + x2r = x0r - (x2r * 2); + x2i = x0i - (x2i * 2); + x1r = x1r + x3r; + x1i = x1i + x3i; + x3r = x1r - (x3r * 2); + x3i = x1i - (x3i * 2); + + x0r = x0r + x1r; + x0i = x0i + x1i; + x1r = x0r - (x1r * 2); + x1i = x0i - (x1i * 2); + x2r = x2r - x3i; + x2i = x2i + x3r; + x3i = x2r + (x3i * 2); + x3r = x2i - (x3r * 2); + + *ptr_y++ = x0r; + *ptr_y++ = x0i; + *ptr_y++ = x2r; + *ptr_y++ = x2i; + *ptr_y++ = x1r; + *ptr_y++ = x1i; + *ptr_y++ = x3i; + *ptr_y++ = x3r; + } + ptr_y -= 2 * npoints; + del = 4; + nodespacing = 64; + in_loop_cnt = npoints >> 4; + for (i = n_stages - 1; i > 0; i--) { + const double *ptr_twiddle = ptr_w; + float *data = ptr_y; + double w_1, w_2, w_3, w_4, w_5, w_6; + int sec_loop_cnt; + + for (k = in_loop_cnt; k != 0; k--) { + x0r = (*data); + x0i = (*(data + 1)); + data += ((SIZE_T)del << 1); + + x1r = (*data); + x1i = (*(data + 1)); + data += ((SIZE_T)del << 1); + + x2r = (*data); + x2i = (*(data + 1)); + data += ((SIZE_T)del << 1); + + x3r = (*data); + x3i = (*(data + 1)); + data -= 3 * (del << 1); + + x0r = x0r + x2r; + x0i = x0i + x2i; + x2r = x0r - (x2r * 2); + x2i = x0i - (x2i * 2); + x1r = x1r + x3r; + x1i = x1i + x3i; + x3r = x1r - (x3r * 2); + x3i = x1i - (x3i * 2); + + x0r = x0r + x1r; + x0i = x0i + x1i; + x1r = x0r - (x1r * 2); + x1i = x0i - (x1i * 2); + x2r = x2r - x3i; + x2i = x2i + x3r; + x3i = x2r + (x3i * 2); + x3r = x2i - (x3r * 2); + + *data = x0r; + *(data + 1) = x0i; + data += ((SIZE_T)del << 1); + + *data = x2r; + *(data + 1) = x2i; + data += ((SIZE_T)del << 1); + + *data = x1r; + *(data + 1) = x1i; + data += ((SIZE_T)del << 1); + + *data = x3i; + *(data + 1) = x3r; + data += ((SIZE_T)del << 1); + } + data = ptr_y + 2; + + sec_loop_cnt = (nodespacing * del); + sec_loop_cnt = (sec_loop_cnt / 4) + (sec_loop_cnt / 8) - (sec_loop_cnt / 16) + + (sec_loop_cnt / 32) - (sec_loop_cnt / 64) + (sec_loop_cnt / 128) - + (sec_loop_cnt / 256); + + for (j = nodespacing; j <= sec_loop_cnt; j += nodespacing) { + w_1 = *(ptr_twiddle + j); + w_4 = *(ptr_twiddle + j + 257); + w_2 = *(ptr_twiddle + ((SIZE_T)j << 1)); + w_5 = *(ptr_twiddle + ((SIZE_T)j << 1) + 257); + w_3 = *(ptr_twiddle + j + ((SIZE_T)j << 1)); + w_6 = *(ptr_twiddle + j + ((SIZE_T)j << 1) + 257); + + for (k = in_loop_cnt; k != 0; k--) { + FLOAT32 tmp; + FLOAT32 x0r1, x0i1, x1r1, x1i1, x2r1, x2i1, x3r1, x3i1; + /*x0 is loaded later to avoid register crunch*/ + + data += ((SIZE_T)del << 1); + + x1r1 = *data; + x1i1 = *(data + 1); + data += ((SIZE_T)del << 1); + + x2r1 = *data; + x2i1 = *(data + 1); + data += ((SIZE_T)del << 1); + + x3r1 = *data; + x3i1 = *(data + 1); + data -= 3 * (del << 1); + + tmp = (FLOAT32)(((FLOAT64)x1r1 * w_1) + ((FLOAT64)x1i1 * w_4)); + x1i1 = (FLOAT32)(-((FLOAT64)x1r1 * w_4) + (FLOAT64)x1i1 * w_1); + x1r1 = tmp; + + tmp = (FLOAT32)(((FLOAT64)x2r1 * w_2) + ((FLOAT64)x2i1 * w_5)); + x2i1 = (FLOAT32)(-((FLOAT64)x2r1 * w_5) + (FLOAT64)x2i1 * w_2); + x2r1 = tmp; + + tmp = (FLOAT32)(((FLOAT64)x3r1 * w_3) + ((FLOAT64)x3i1 * w_6)); + x3i1 = (FLOAT32)(-((FLOAT64)x3r1 * w_6) + (FLOAT64)x3i1 * w_3); + x3r1 = tmp; + + x0r1 = (*data); + x0i1 = (*(data + 1)); + + x0r1 = x0r1 + (x2r1); + x0i1 = x0i1 + (x2i1); + x2r1 = x0r1 - (x2r1 * 2); + x2i1 = x0i1 - (x2i1 * 2); + x1r1 = x1r1 + x3r1; + x1i1 = x1i1 + x3i1; + x3r1 = x1r1 - (x3r1 * 2); + x3i1 = x1i1 - (x3i1 * 2); + + x0r1 = x0r1 + (x1r1); + x0i1 = x0i1 + (x1i1); + x1r1 = x0r1 - (x1r1 * 2); + x1i1 = x0i1 - (x1i1 * 2); + x2r1 = x2r1 - (x3i1); + x2i1 = x2i1 + (x3r1); + x3i1 = x2r1 + (x3i1 * 2); + x3r1 = x2i1 - (x3r1 * 2); + + *data = x0r1; + *(data + 1) = x0i1; + data += ((SIZE_T)del << 1); + + *data = x2r1; + *(data + 1) = x2i1; + data += ((SIZE_T)del << 1); + + *data = x1r1; + *(data + 1) = x1i1; + data += ((SIZE_T)del << 1); + + *data = x3i1; + *(data + 1) = x3r1; + data += ((SIZE_T)del << 1); + } + data -= 2 * npoints; + data += 2; + } + for (; j <= (nodespacing * del) >> 1; j += nodespacing) { + w_1 = *(ptr_twiddle + j); + w_4 = *(ptr_twiddle + j + 257); + w_2 = *(ptr_twiddle + ((SIZE_T)j << 1)); + w_5 = *(ptr_twiddle + ((SIZE_T)j << 1) + 257); + w_3 = *(ptr_twiddle + j + ((SIZE_T)j << 1) - 256); + w_6 = *(ptr_twiddle + j + ((SIZE_T)j << 1) + 1); + + for (k = in_loop_cnt; k != 0; k--) { + FLOAT32 tmp; + FLOAT32 x0r1, x0i1, x1r1, x1i1, x2r1, x2i1, x3r1, x3i1; + /*x0 is loaded later to avoid register crunch*/ + + data += ((SIZE_T)del << 1); + + x1r1 = *data; + x1i1 = *(data + 1); + data += ((SIZE_T)del << 1); + + x2r1 = *data; + x2i1 = *(data + 1); + data += ((SIZE_T)del << 1); + + x3r1 = *data; + x3i1 = *(data + 1); + data -= 3 * (del << 1); + + tmp = (FLOAT32)(((FLOAT64)x1r1 * w_1) + ((FLOAT64)x1i1 * w_4)); + x1i1 = (FLOAT32)(-((FLOAT64)x1r1 * w_4) + (FLOAT64)x1i1 * w_1); + x1r1 = tmp; + + tmp = (FLOAT32)(((FLOAT64)x2r1 * w_2) + ((FLOAT64)x2i1 * w_5)); + x2i1 = (FLOAT32)(-((FLOAT64)x2r1 * w_5) + (FLOAT64)x2i1 * w_2); + x2r1 = tmp; + + tmp = (FLOAT32)(((FLOAT64)x3r1 * w_6) - ((FLOAT64)x3i1 * w_3)); + x3i1 = (FLOAT32)(((FLOAT64)x3r1 * w_3) + ((FLOAT64)x3i1 * w_6)); + x3r1 = tmp; + + x0r1 = (*data); + x0i1 = (*(data + 1)); + + x0r1 = x0r1 + (x2r1); + x0i1 = x0i1 + (x2i1); + x2r1 = x0r1 - (x2r1 * 2); + x2i1 = x0i1 - (x2i1 * 2); + x1r1 = x1r1 + x3r1; + x1i1 = x1i1 + x3i1; + x3r1 = x1r1 - (x3r1 * 2); + x3i1 = x1i1 - (x3i1 * 2); + + x0r1 = x0r1 + (x1r1); + x0i1 = x0i1 + (x1i1); + x1r1 = x0r1 - (x1r1 * 2); + x1i1 = x0i1 - (x1i1 * 2); + x2r1 = x2r1 - (x3i1); + x2i1 = x2i1 + (x3r1); + x3i1 = x2r1 + (x3i1 * 2); + x3r1 = x2i1 - (x3r1 * 2); + + *data = x0r1; + *(data + 1) = x0i1; + data += ((SIZE_T)del << 1); + + *data = x2r1; + *(data + 1) = x2i1; + data += ((SIZE_T)del << 1); + + *data = x1r1; + *(data + 1) = x1i1; + data += ((SIZE_T)del << 1); + + *data = x3i1; + *(data + 1) = x3r1; + data += ((SIZE_T)del << 1); + } + data -= 2 * npoints; + data += 2; + } + for (; j <= sec_loop_cnt * 2; j += nodespacing) { + w_1 = *(ptr_twiddle + j); + w_4 = *(ptr_twiddle + j + 257); + w_2 = *(ptr_twiddle + ((SIZE_T)j << 1) - 256); + w_5 = *(ptr_twiddle + ((SIZE_T)j << 1) + 1); + w_3 = *(ptr_twiddle + j + ((SIZE_T)j << 1) - 256); + w_6 = *(ptr_twiddle + j + ((SIZE_T)j << 1) + 1); + + for (k = in_loop_cnt; k != 0; k--) { + FLOAT32 tmp; + FLOAT32 x0r1, x0i1, x1r1, x1i1, x2r1, x2i1, x3r1, x3i1; + /*x0 is loaded later to avoid register crunch*/ + + data += ((SIZE_T)del << 1); + + x1r1 = *data; + x1i1 = *(data + 1); + data += ((SIZE_T)del << 1); + + x2r1 = *data; + x2i1 = *(data + 1); + data += ((SIZE_T)del << 1); + + x3r1 = *data; + x3i1 = *(data + 1); + data -= 3 * (del << 1); + + tmp = (FLOAT32)(((FLOAT64)x1r1 * w_1) + ((FLOAT64)x1i1 * w_4)); + x1i1 = (FLOAT32)(-((FLOAT64)x1r1 * w_4) + (FLOAT64)x1i1 * w_1); + x1r1 = tmp; + + tmp = (FLOAT32)(((FLOAT64)x2r1 * w_5) - ((FLOAT64)x2i1 * w_2)); + x2i1 = (FLOAT32)(((FLOAT64)x2r1 * w_2) + ((FLOAT64)x2i1 * w_5)); + x2r1 = tmp; + + tmp = (FLOAT32)(((FLOAT64)x3r1 * w_6) - ((FLOAT64)x3i1 * w_3)); + x3i1 = (FLOAT32)(((FLOAT64)x3r1 * w_3) + ((FLOAT64)x3i1 * w_6)); + x3r1 = tmp; + + x0r1 = (*data); + x0i1 = (*(data + 1)); + + x0r1 = x0r1 + (x2r1); + x0i1 = x0i1 + (x2i1); + x2r1 = x0r1 - (x2r1 * 2); + x2i1 = x0i1 - (x2i1 * 2); + x1r1 = x1r1 + x3r1; + x1i1 = x1i1 + x3i1; + x3r1 = x1r1 - (x3r1 * 2); + x3i1 = x1i1 - (x3i1 * 2); + + x0r1 = x0r1 + (x1r1); + x0i1 = x0i1 + (x1i1); + x1r1 = x0r1 - (x1r1 * 2); + x1i1 = x0i1 - (x1i1 * 2); + x2r1 = x2r1 - (x3i1); + x2i1 = x2i1 + (x3r1); + x3i1 = x2r1 + (x3i1 * 2); + x3r1 = x2i1 - (x3r1 * 2); + + *data = x0r1; + *(data + 1) = x0i1; + data += ((SIZE_T)del << 1); + + *data = x2r1; + *(data + 1) = x2i1; + data += ((SIZE_T)del << 1); + + *data = x1r1; + *(data + 1) = x1i1; + data += ((SIZE_T)del << 1); + + *data = x3i1; + *(data + 1) = x3r1; + data += ((SIZE_T)del << 1); + } + data -= 2 * npoints; + data += 2; + } + for (; j < nodespacing * del; j += nodespacing) { + w_1 = *(ptr_twiddle + j); + w_4 = *(ptr_twiddle + j + 257); + w_2 = *(ptr_twiddle + ((SIZE_T)j << 1) - 256); + w_5 = *(ptr_twiddle + ((SIZE_T)j << 1) + 1); + w_3 = *(ptr_twiddle + j + ((SIZE_T)j << 1) - 512); + w_6 = *(ptr_twiddle + j + ((SIZE_T)j << 1) - 512 + 257); + + for (k = in_loop_cnt; k != 0; k--) { + FLOAT32 tmp; + FLOAT32 x0r1, x0i1, x1r1, x1i1, x2r1, x2i1, x3r1, x3i1; + /*x0 is loaded later to avoid register crunch*/ + + data += ((SIZE_T)del << 1); + + x1r1 = *data; + x1i1 = *(data + 1); + data += ((SIZE_T)del << 1); + + x2r1 = *data; + x2i1 = *(data + 1); + data += ((SIZE_T)del << 1); + + x3r1 = *data; + x3i1 = *(data + 1); + data -= 3 * (del << 1); + + tmp = (FLOAT32)(((FLOAT64)x1r1 * w_1) + ((FLOAT64)x1i1 * w_4)); + x1i1 = (FLOAT32)(-((FLOAT64)x1r1 * w_4) + (FLOAT64)x1i1 * w_1); + x1r1 = tmp; + + tmp = (FLOAT32)(((FLOAT64)x2r1 * w_5) - ((FLOAT64)x2i1 * w_2)); + x2i1 = (FLOAT32)(((FLOAT64)x2r1 * w_2) + ((FLOAT64)x2i1 * w_5)); + x2r1 = tmp; + + tmp = (FLOAT32)(-((FLOAT64)x3r1 * w_3) - ((FLOAT64)x3i1 * w_6)); + x3i1 = (FLOAT32)(-((FLOAT64)x3r1 * w_6) + (FLOAT64)x3i1 * w_3); + x3r1 = tmp; + + x0r1 = (*data); + x0i1 = (*(data + 1)); + + x0r1 = x0r1 + (x2r1); + x0i1 = x0i1 + (x2i1); + x2r1 = x0r1 - (x2r1 * 2); + x2i1 = x0i1 - (x2i1 * 2); + x1r1 = x1r1 + x3r1; + x1i1 = x1i1 - x3i1; + x3r1 = x1r1 - (x3r1 * 2); + x3i1 = x1i1 + (x3i1 * 2); + + x0r1 = x0r1 + (x1r1); + x0i1 = x0i1 + (x1i1); + x1r1 = x0r1 - (x1r1 * 2); + x1i1 = x0i1 - (x1i1 * 2); + x2r1 = x2r1 - (x3i1); + x2i1 = x2i1 + (x3r1); + x3i1 = x2r1 + (x3i1 * 2); + x3r1 = x2i1 - (x3r1 * 2); + + *data = x0r1; + *(data + 1) = x0i1; + data += ((SIZE_T)del << 1); + + *data = x2r1; + *(data + 1) = x2i1; + data += ((SIZE_T)del << 1); + + *data = x1r1; + *(data + 1) = x1i1; + data += ((SIZE_T)del << 1); + + *data = x3i1; + *(data + 1) = x3r1; + data += ((SIZE_T)del << 1); + } + data -= 2 * npoints; + data += 2; + } + nodespacing >>= 2; + del <<= 2; + in_loop_cnt >>= 2; + } + + if (not_power_4) { + const FLOAT64 *ptr_twiddle = ptr_w; + nodespacing <<= 1; + + for (j = del / 2; j != 0; j--) { + FLOAT64 w_1 = *ptr_twiddle; + FLOAT64 w_4 = *(ptr_twiddle + 257); + FLOAT32 tmp; + ptr_twiddle += nodespacing; + + x0r = *ptr_y; + x0i = *(ptr_y + 1); + ptr_y += ((SIZE_T)del << 1); + + x1r = *ptr_y; + x1i = *(ptr_y + 1); + + tmp = (FLOAT32)(((FLOAT64)x1r * w_1) + ((FLOAT64)x1i * w_4)); + x1i = (FLOAT32)(-((FLOAT64)x1r * w_4) + (FLOAT64)x1i * w_1); + x1r = tmp; + + *ptr_y = (x0r) - (x1r); + *(ptr_y + 1) = (x0i) - (x1i); + ptr_y -= ((SIZE_T)del << 1); + + *ptr_y = (x0r) + (x1r); + *(ptr_y + 1) = (x0i) + (x1i); + ptr_y += 2; + } + ptr_twiddle = ptr_w; + for (j = del / 2; j != 0; j--) { + FLOAT64 w_1 = *ptr_twiddle; + FLOAT64 w_4 = *(ptr_twiddle + 257); + FLOAT32 tmp; + ptr_twiddle += nodespacing; + + x0r = *ptr_y; + x0i = *(ptr_y + 1); + ptr_y += ((SIZE_T)del << 1); + + x1r = *ptr_y; + x1i = *(ptr_y + 1); + + tmp = (FLOAT32)(((FLOAT64)x1r * w_4) - ((FLOAT64)x1i * w_1)); + x1i = (FLOAT32)(((FLOAT64)x1r * w_1) + ((FLOAT64)x1i * w_4)); + x1r = tmp; + + *ptr_y = (x0r) - (x1r); + *(ptr_y + 1) = (x0i) - (x1i); + ptr_y -= ((SIZE_T)del << 1); + + *ptr_y = (x0r) + (x1r); + *(ptr_y + 1) = (x0i) + (x1i); + ptr_y += 2; + } + } + } + + for (i = 0; i < n_pass; i++) { + re[2 * i + 0] = y[2 * i + 0]; + re[2 * i + 1] = y[2 * i + 1]; + } +} + +VOID ixheaace_hbe_apply_cfftn_gen(FLOAT32 in[], FLOAT32 *ptr_scratch, WORD32 n_pass, + WORD32 i_sign) { + WORD32 i, j; + WORD32 m_points = n_pass; + FLOAT32 *y, *re_3; + FLOAT32 *ptr_x, *ptr_y; + ptr_x = ptr_scratch; + ptr_scratch += 2 * m_points; + ptr_y = y = ptr_scratch; + ptr_scratch += 4 * m_points; + re_3 = ptr_scratch; + ptr_scratch += 2 * m_points; + WORD32 cnfac; + WORD32 mpass = n_pass; + + cnfac = 0; + while (mpass % 3 == 0) { + mpass /= 3; + cnfac++; + } + + for (i = 0; i < 3 * cnfac; i++) { + for (j = 0; j < mpass; j++) { + re_3[2 * j + 0] = in[6 * j + 2 * i + 0]; + re_3[2 * j + 1] = in[6 * j + 2 * i + 1]; + } + + ixheaace_hbe_apply_cfftn(re_3, ptr_scratch, mpass, i_sign); + + for (j = 0; j < mpass; j++) { + in[6 * j + 2 * i + 0] = re_3[2 * j + 0]; + in[6 * j + 2 * i + 1] = re_3[2 * j + 1]; + } + } + + { + FLOAT64 *ptr_w1r, *ptr_w1i; + FLOAT32 tmp; + ptr_w1r = (FLOAT64 *)ixheaac_twid_tbl_fft_ntwt3r; + ptr_w1i = (FLOAT64 *)ixheaac_twid_tbl_fft_ntwt3i; + + if (i_sign < 0) { + i = 0; + while (i < n_pass) { + tmp = + (FLOAT32)((FLOAT64)in[2 * i + 0] * (*ptr_w1r) - (FLOAT64)in[2 * i + 1] * (*ptr_w1i)); + in[2 * i + 1] = + (FLOAT32)((FLOAT64)in[2 * i + 0] * (*ptr_w1i) + (FLOAT64)in[2 * i + 1] * (*ptr_w1r)); + in[2 * i + 0] = tmp; + + ptr_w1r++; + ptr_w1i++; + + tmp = + (FLOAT32)((FLOAT64)in[2 * i + 2] * (*ptr_w1r) - (FLOAT64)in[2 * i + 3] * (*ptr_w1i)); + in[2 * i + 3] = + (FLOAT32)((FLOAT64)in[2 * i + 2] * (*ptr_w1i) + (FLOAT64)in[2 * i + 3] * (*ptr_w1r)); + in[2 * i + 2] = tmp; + + ptr_w1r++; + ptr_w1i++; + + tmp = + (FLOAT32)((FLOAT64)in[2 * i + 4] * (*ptr_w1r) - (FLOAT64)in[2 * i + 5] * (*ptr_w1i)); + in[2 * i + 5] = + (FLOAT32)((FLOAT64)in[2 * i + 4] * (*ptr_w1i) + (FLOAT64)in[2 * i + 5] * (*ptr_w1r)); + in[2 * i + 4] = tmp; + + ptr_w1r += 3 * (128 / mpass - 1) + 1; + ptr_w1i += 3 * (128 / mpass - 1) + 1; + i += 3; + } + } + + else { + i = 0; + while (i < n_pass) { + tmp = + (FLOAT32)((FLOAT64)in[2 * i + 0] * (*ptr_w1r) + (FLOAT64)in[2 * i + 1] * (*ptr_w1i)); + in[2 * i + 1] = + (FLOAT32)(-(FLOAT64)in[2 * i + 0] * (*ptr_w1i) + (FLOAT64)in[2 * i + 1] * (*ptr_w1r)); + in[2 * i + 0] = tmp; + + ptr_w1r++; + ptr_w1i++; + + tmp = + (FLOAT32)((FLOAT64)in[2 * i + 2] * (*ptr_w1r) + (FLOAT64)in[2 * i + 3] * (*ptr_w1i)); + in[2 * i + 3] = + (FLOAT32)(-(FLOAT64)in[2 * i + 2] * (*ptr_w1i) + (FLOAT64)in[2 * i + 3] * (*ptr_w1r)); + in[2 * i + 2] = tmp; + + ptr_w1r++; + ptr_w1i++; + + tmp = + (FLOAT32)((FLOAT64)in[2 * i + 4] * (*ptr_w1r) + (FLOAT64)in[2 * i + 5] * (*ptr_w1i)); + in[2 * i + 5] = + (FLOAT32)(-(FLOAT64)in[2 * i + 4] * (*ptr_w1i) + (FLOAT64)in[2 * i + 5] * (*ptr_w1r)); + in[2 * i + 4] = tmp; + + ptr_w1r += 3 * (128 / mpass - 1) + 1; + ptr_w1i += 3 * (128 / mpass - 1) + 1; + i += 3; + } + } + } + + for (i = 0; i < n_pass; i++) { + ptr_x[2 * i + 0] = in[2 * i + 0]; + ptr_x[2 * i + 1] = in[2 * i + 1]; + } + for (i = 0; i < mpass; i++) { + ixheaace_hbe_apply_fft_3(ptr_x, ptr_y, i_sign); + + ptr_x = ptr_x + 6; + ptr_y = ptr_y + 6; + } + + for (i = 0; i < mpass; i++) { + in[2 * i + 0] = y[6 * i + 0]; + in[2 * i + 1] = y[6 * i + 1]; + } + + for (i = 0; i < mpass; i++) { + in[2 * mpass + 2 * i + 0] = y[6 * i + 2]; + in[2 * mpass + 2 * i + 1] = y[6 * i + 3]; + } + + for (i = 0; i < mpass; i++) { + in[4 * mpass + 2 * i + 0] = y[6 * i + 4]; + in[4 * mpass + 2 * i + 1] = y[6 * i + 5]; + } +} + +VOID ixheaace_hbe_apply_fft_288(FLOAT32 *ptr_inp, FLOAT32 *ptr_scratch, WORD32 len, + WORD32 i_sign) { + /* Dividing the 288-point FFT into 96x3 i.e nx3*/ + FLOAT32 *ptr_op = ptr_scratch; + WORD32 mpoints = len / 96; + WORD32 fpoints = len / 3; + WORD32 ii, jj; + ptr_scratch += 2 * len; + + for (ii = 0; ii < mpoints; ii++) { + for (jj = 0; jj < fpoints; jj++) { + ptr_op[2 * jj + 0] = ptr_inp[2 * mpoints * jj + 2 * ii]; + ptr_op[2 * jj + 1] = ptr_inp[2 * mpoints * jj + 2 * ii + 1]; + } + + /* 96-point (32x3-point) of FFT */ + if (fpoints & (fpoints - 1)) + ixheaace_hbe_apply_cfftn_gen(ptr_op, ptr_scratch, fpoints, i_sign); + else + ixheaace_hbe_apply_cfftn(ptr_op, ptr_scratch, fpoints, i_sign); + + for (jj = 0; jj < fpoints; jj++) { + ptr_inp[mpoints * 2 * jj + 2 * ii + 0] = ptr_op[2 * jj + 0]; + ptr_inp[mpoints * 2 * jj + 2 * ii + 1] = ptr_op[2 * jj + 1]; + } + } + + /* Multiplication FFT with twiddle table */ + ixheaace_hbe_apply_tw_mult_fft(ptr_inp, ptr_op, fpoints, mpoints, ixheaac_twid_tbl_fft_288); + + for (ii = 0; ii < fpoints; ii++) { + /* 3-point of FFT */ + ixheaace_hbe_apply_fft_3(ptr_op, ptr_scratch, i_sign); + ptr_op = ptr_op + (mpoints * 2); + ptr_scratch = ptr_scratch + (mpoints * 2); + } + + ptr_scratch -= fpoints * mpoints * 2; + + for (jj = 0; jj < fpoints; jj++) { + ptr_inp[2 * jj + 0] = ptr_scratch[6 * jj]; + ptr_inp[2 * jj + 1] = ptr_scratch[6 * jj + 1]; + } + for (jj = 0; jj < fpoints; jj++) { + ptr_inp[2 * fpoints + 2 * jj + 0] = ptr_scratch[6 * jj + 2]; + ptr_inp[2 * fpoints + 2 * jj + 1] = ptr_scratch[6 * jj + 3]; + } + for (jj = 0; jj < fpoints; jj++) { + ptr_inp[4 * fpoints + 2 * jj + 0] = ptr_scratch[6 * jj + 4]; + ptr_inp[4 * fpoints + 2 * jj + 1] = ptr_scratch[6 * jj + 5]; + } +} + +VOID ixheaace_hbe_apply_ifft_224(FLOAT32 *ptr_inp, FLOAT32 *ptr_scratch, WORD32 len, + WORD32 i_sign) { + /* Dividing 224-point IFFT into 32x7 */ + WORD32 mpoints = len / 32; + WORD32 fpoints = len / 7; + WORD32 ii, jj; + FLOAT32 *ptr_op = ptr_scratch; + ptr_scratch += 2 * len; + + for (ii = 0; ii < mpoints; ii++) { + for (jj = 0; jj < fpoints; jj++) { + ptr_op[2 * jj + 0] = ptr_inp[2 * mpoints * jj + 2 * ii]; + ptr_op[2 * jj + 1] = ptr_inp[2 * mpoints * jj + 2 * ii + 1]; + } + + /* 32-point of IFFT*/ + if (fpoints & (fpoints - 1)) + ixheaace_hbe_apply_cfftn_gen(ptr_op, ptr_scratch, fpoints, i_sign); + else + ixheaace_hbe_apply_cfftn(ptr_op, ptr_scratch, fpoints, i_sign); + + for (jj = 0; jj < fpoints; jj++) { + ptr_inp[mpoints * 2 * jj + 2 * ii + 0] = ptr_op[2 * jj + 0]; + ptr_inp[mpoints * 2 * jj + 2 * ii + 1] = ptr_op[2 * jj + 1]; + } + } + + /* Multiplication IFFT with twiddle table */ + ixheaace_hbe_apply_tw_mult_ifft(ptr_inp, ptr_op, fpoints, mpoints, ixheaac_twid_tbl_fft_224); + + for (ii = 0; ii < fpoints; ii++) { + /* 7-point of IFFT */ + ixheaace_hbe_apply_ifft_7(ptr_op, ptr_scratch); + ptr_scratch += (mpoints * 2); + ptr_op += (mpoints * 2); + } + + ptr_scratch -= fpoints * mpoints * 2; + + for (jj = 0; jj < fpoints; jj++) { + for (ii = 0; ii < mpoints; ii++) { + ptr_inp[fpoints * ii * 2 + 2 * jj + 0] = ptr_scratch[mpoints * jj * 2 + 2 * ii + 0]; + ptr_inp[fpoints * ii * 2 + 2 * jj + 1] = ptr_scratch[mpoints * jj * 2 + 2 * ii + 1]; + } + } +} + +VOID ixheaace_hbe_apply_ifft_336(FLOAT32 *ptr_inp, FLOAT32 *ptr_scratch, WORD32 len, + WORD32 i_sign) { + WORD32 i, j; + WORD32 m_points = len / 7; + WORD32 n_points = len / 48; + FLOAT32 *ptr_real, *ptr_imag, *ptr_real_1, *ptr_scratch_local; + ptr_real = ptr_scratch; + ptr_scratch += 2 * len; + ptr_imag = ptr_scratch; + ptr_scratch += len; + ptr_scratch_local = ptr_scratch; + ptr_scratch += len; + ptr_real_1 = ptr_scratch; + ptr_scratch += len; + + for (i = 0; i < len; i++) { + ptr_real[i] = ptr_inp[2 * i + 0]; + ptr_imag[i] = ptr_inp[2 * i + 1]; + } + + for (i = 0; i < m_points; i++) { + for (j = 0; j < n_points; j++) { + ptr_real_1[2 * j + 0] = ptr_inp[m_points * 2 * j + 2 * i + 0]; + ptr_real_1[2 * j + 1] = ptr_inp[m_points * 2 * j + 2 * i + 1]; + } + + ixheaace_hbe_apply_ifft_7(ptr_real_1, ptr_scratch); + + for (j = 0; j < n_points; j++) { + ptr_inp[m_points * 2 * j + 2 * i + 0] = ptr_scratch[2 * j + 0]; + ptr_inp[m_points * 2 * j + 2 * i + 1] = ptr_scratch[2 * j + 1]; + } + } + + switch (m_points) { + case 48: + ixheaace_hbe_apply_tw_mult_ifft(ptr_inp, ptr_scratch_local, n_points, m_points, + ixheaac_twid_tbl_fft_336); + break; + + default: + ixheaace_hbe_apply_tw_mult_ifft(ptr_inp, ptr_scratch_local, n_points, m_points, + ixheaac_twid_tbl_fft_168); + break; + } + for (i = 0; i < len; i++) { + ptr_real[2 * i + 0] = ptr_scratch_local[2 * i + 0]; + ptr_real[2 * i + 1] = ptr_scratch_local[2 * i + 1]; + } + + for (i = 0; i < n_points; i++) { + ixheaace_hbe_apply_cfftn_gen(ptr_real, ptr_scratch, m_points, i_sign); + ptr_real += (2 * m_points); + } + + ptr_real -= n_points * 2 * m_points; + + for (j = 0; j < n_points; j++) { + for (i = 0; i < m_points; i++) { + ptr_inp[n_points * 2 * i + 2 * j + 0] = ptr_real[2 * m_points * j + 2 * i + 0]; + ptr_inp[n_points * 2 * i + 2 * j + 1] = ptr_real[2 * m_points * j + 2 * i + 1]; + } + } +} diff --git a/encoder/ixheaace_sbr_hbe_polyphase.c b/encoder/ixheaace_sbr_hbe_polyphase.c new file mode 100644 index 0000000..40f77ea --- /dev/null +++ b/encoder/ixheaace_sbr_hbe_polyphase.c @@ -0,0 +1,329 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ +#include "ixheaac_type_def.h" +#include "ixheaace_bitbuffer.h" +#include "ixheaac_error_standards.h" +#include "ixheaace_error_codes.h" + +#include "iusace_tns_usac.h" +#include "iusace_cnst.h" +#include "ixheaace_sbr_def.h" +#include "ixheaace_resampler.h" +#include "ixheaace_sbr_hbe.h" +#include "ixheaace_sbr_hbe_fft.h" +#include "ixheaac_esbr_rom.h" +#include + +IA_ERRORCODE ixheaace_complex_anal_filt(ixheaace_str_esbr_hbe_txposer *ptr_hbe_txposer) { + WORD32 idx; + WORD32 anal_size = 2 * ptr_hbe_txposer->synth_size; + WORD32 N = (10 * anal_size); + + WORD32 no_bins = ptr_hbe_txposer->no_bins >> 1; + + if (ptr_hbe_txposer->esbr_hq != 0) { + anal_size = 2 * ptr_hbe_txposer->analy_size; + no_bins = ptr_hbe_txposer->no_bins; + } + + idx = 0; + while (idx < no_bins) { + WORD32 i, j, k, l; + FLOAT32 window_output[640] = {0}; + FLOAT32 u[128] = {0}, u_in[256] = {0}, u_out[256] = {0}; + FLOAT32 accu_r, accu_i; + const FLOAT32 *ptr_inp_signal; + FLOAT32 *ptr_anal_buf; + + FLOAT32 *ptr_analy_cos_sin_tab = ptr_hbe_txposer->ptr_analy_cos_sin_tab; + const FLOAT32 *ptr_interp_window_coeff = ptr_hbe_txposer->ptr_ana_win_coeff; + FLOAT32 *ptr_x = ptr_hbe_txposer->analy_buf; + + if (ptr_hbe_txposer->esbr_hq != 0) { + memset(ptr_hbe_txposer->qmf_in_buf[idx], 0, sizeof(ptr_hbe_txposer->qmf_in_buf[idx])); + ptr_inp_signal = ptr_hbe_txposer->ptr_output_buf + idx * ptr_hbe_txposer->analy_size + 1; + ptr_anal_buf = &ptr_hbe_txposer->qmf_in_buf[idx][4 * ptr_hbe_txposer->a_start]; + } else { + memset(ptr_hbe_txposer->qmf_in_buf[idx + IXHEAACE_HBE_OPER_WIN_LEN - 1], 0, + sizeof(ptr_hbe_txposer->qmf_in_buf[idx + IXHEAACE_HBE_OPER_WIN_LEN - 1])); + + ptr_inp_signal = ptr_hbe_txposer->ptr_input_buf + idx * 2 * ptr_hbe_txposer->synth_size + 1; + ptr_anal_buf = + &ptr_hbe_txposer + ->qmf_in_buf[idx + IXHEAACE_HBE_OPER_WIN_LEN - 1][4 * ptr_hbe_txposer->k_start]; + } + + for (i = N - 1; i >= anal_size; i--) { + ptr_x[i] = ptr_x[i - anal_size]; + } + + for (i = anal_size - 1; i >= 0; i--) { + ptr_x[i] = ptr_inp_signal[anal_size - 1 - i]; + } + + for (i = 0; i < N; i++) { + window_output[i] = ptr_x[i] * ptr_interp_window_coeff[i]; + } + + for (i = 0; i < 2 * anal_size; i++) { + accu_r = 0.0; + for (j = 0; j < 5; j++) { + accu_r = accu_r + window_output[i + j * 2 * anal_size]; + } + u[i] = accu_r; + } + if (anal_size == 40 || anal_size == 56) { + for (i = 1; i < anal_size; i++) { + FLOAT32 temp1 = u[i] + u[2 * anal_size - i]; + FLOAT32 temp2 = u[i] - u[2 * anal_size - i]; + u[i] = temp1; + u[2 * anal_size - i] = temp2; + } + + k = 0; + while (k < anal_size) { + accu_r = u[anal_size]; + if (k & 1) + accu_i = u[0]; + else + accu_i = -u[0]; + for (l = 1; l < anal_size; l++) { + accu_r = accu_r + u[0 + l] * ptr_analy_cos_sin_tab[2 * l + 0]; + accu_i = accu_i + u[2 * anal_size - l] * ptr_analy_cos_sin_tab[2 * l + 1]; + } + ptr_analy_cos_sin_tab += (2 * anal_size); + *ptr_anal_buf++ = (FLOAT32)accu_r; + *ptr_anal_buf++ = (FLOAT32)accu_i; + k++; + } + } else { + FLOAT32 *ptr_u = u_in; + FLOAT32 *ptr_v = u_out; + for (k = 0; k < anal_size * 2; k++) { + *ptr_u++ = ((*ptr_analy_cos_sin_tab++) * u[k]); + *ptr_u++ = ((*ptr_analy_cos_sin_tab++) * u[k]); + } + if (ptr_hbe_txposer->ixheaace_cmplx_anal_fft != NULL) { + (*(ptr_hbe_txposer->ixheaace_cmplx_anal_fft))(u_in, u_out, anal_size * 2); + } else { + return IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_FFT; + } + + for (k = 0; k < anal_size / 2; k++) { + *(ptr_anal_buf + 1) = -*ptr_v++; + *ptr_anal_buf = *ptr_v++; + + ptr_anal_buf += 2; + + *(ptr_anal_buf + 1) = *ptr_v++; + *ptr_anal_buf = -*ptr_v++; + + ptr_anal_buf += 2; + } + } + idx++; + } + return IA_NO_ERROR; +} + +IA_ERRORCODE ixheaace_real_synth_filt(ixheaace_str_esbr_hbe_txposer *ptr_hbe_txposer, + WORD32 num_columns, FLOAT32 qmf_buf_real[][64], + FLOAT32 qmf_buf_imag[][64]) { + WORD32 i, j, k, l, idx; + FLOAT32 g[640]; + FLOAT32 w[640]; + FLOAT32 synth_out[128]; + FLOAT32 accu_r; + WORD32 synth_size = ptr_hbe_txposer->synth_size; + FLOAT32 *ptr_cos_tab_trans_qmf = + (FLOAT32 *)&ixheaac_cos_table_trans_qmf[0][0] + ptr_hbe_txposer->k_start * 32; + FLOAT32 *ptr_buffer = ptr_hbe_txposer->synth_buf; + FLOAT32 *ptr_inp_buf = ptr_hbe_txposer->ptr_input_buf + ptr_hbe_txposer->ana_fft_size[0]; + + for (idx = 0; idx < num_columns; idx++) { + FLOAT32 loc_qmf_buf[64]; + FLOAT32 *ptr_synth_buf_r = loc_qmf_buf; + FLOAT32 *ptr_out_buf; + if (ptr_hbe_txposer->esbr_hq == 1) { + ptr_out_buf = ptr_inp_buf + (idx - 1) * ptr_hbe_txposer->synth_size; + } else { + ptr_out_buf = ptr_hbe_txposer->ptr_input_buf + (idx + 1) * ptr_hbe_txposer->synth_size; + } + + FLOAT32 *ptr_synth_cos_tab = ptr_hbe_txposer->ptr_syn_cos_tab; + const FLOAT32 *ptr_interp_window_coeff = ptr_hbe_txposer->ptr_syn_win_coeff; + if (ptr_hbe_txposer->k_start < 0) { + return IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_START_BAND; + } + + k = 0; + while (k < synth_size) { + WORD32 ki = ptr_hbe_txposer->k_start + k; + ptr_synth_buf_r[k] = (FLOAT32)(ptr_cos_tab_trans_qmf[(k << 1) + 0] * qmf_buf_real[idx][ki] + + ptr_cos_tab_trans_qmf[(k << 1) + 1] * qmf_buf_imag[idx][ki]); + + ptr_synth_buf_r[k + ptr_hbe_txposer->synth_size] = 0; + k++; + } + + for (l = (20 * synth_size - 1); l >= 2 * synth_size; l--) { + ptr_buffer[l] = ptr_buffer[l - 2 * synth_size]; + } + + if (synth_size == 20) { + FLOAT32 *ptr_psynth_cos_tab = ptr_synth_cos_tab; + + for (l = 0; l < (synth_size + 1); l++) { + accu_r = 0.0; + for (k = 0; k < synth_size; k++) { + accu_r += ptr_synth_buf_r[k] * ptr_psynth_cos_tab[k]; + } + ptr_buffer[0 + l] = accu_r; + ptr_buffer[synth_size - l] = accu_r; + ptr_psynth_cos_tab = ptr_psynth_cos_tab + synth_size; + } + for (l = (synth_size + 1); l < (2 * synth_size - synth_size / 2); l++) { + accu_r = 0.0; + for (k = 0; k < synth_size; k++) { + accu_r += ptr_synth_buf_r[k] * ptr_psynth_cos_tab[k]; + } + ptr_buffer[0 + l] = accu_r; + ptr_buffer[3 * synth_size - l] = -accu_r; + ptr_psynth_cos_tab = ptr_psynth_cos_tab + synth_size; + } + accu_r = 0.0; + for (k = 0; k < synth_size; k++) { + accu_r += ptr_synth_buf_r[k] * ptr_psynth_cos_tab[k]; + } + ptr_buffer[3 * synth_size >> 1] = accu_r; + } else { + FLOAT32 tmp; + FLOAT32 *ptr_u = synth_out; + WORD32 kmax = (synth_size >> 1); + FLOAT32 *ptr_syn_buf = &ptr_buffer[kmax]; + kmax += synth_size; + + if (ptr_hbe_txposer->ixheaace_real_synth_fft != NULL) { + (*(ptr_hbe_txposer->ixheaace_real_synth_fft))(ptr_synth_buf_r, synth_out, synth_size * 2); + } else { + return IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_FFT; + } + + for (k = 0; k < kmax; k++) { + tmp = ((*ptr_u++) * (*ptr_synth_cos_tab++)); + tmp -= ((*ptr_u++) * (*ptr_synth_cos_tab++)); + *ptr_syn_buf++ = tmp; + } + + ptr_syn_buf = &ptr_buffer[0]; + kmax -= synth_size; + + for (k = 0; k < kmax; k++) { + tmp = ((*ptr_u++) * (*ptr_synth_cos_tab++)); + tmp -= ((*ptr_u++) * (*ptr_synth_cos_tab++)); + *ptr_syn_buf++ = tmp; + } + } + + for (i = 0; i < 5; i++) { + memcpy(&g[(2 * i + 0) * synth_size], &ptr_buffer[(4 * i + 0) * synth_size], + sizeof(g[0]) * synth_size); + memcpy(&g[(2 * i + 1) * synth_size], &ptr_buffer[(4 * i + 3) * synth_size], + sizeof(g[0]) * synth_size); + } + + for (k = 0; k < 10 * synth_size; k++) { + w[k] = g[k] * ptr_interp_window_coeff[k]; + } + + for (i = 0; i < synth_size; i++) { + accu_r = 0.0; + for (j = 0; j < 10; j++) { + accu_r = accu_r + w[synth_size * j + i]; + } + ptr_out_buf[i] = (FLOAT32)accu_r; + } + } + return IA_NO_ERROR; +} + +VOID ixheaace_dft_hbe_cplx_anal_filt(ixheaace_str_esbr_hbe_txposer *ptr_hbe_txposer, + FLOAT32 qmf_buf_real[][64], FLOAT32 qmf_buf_imag[][64]) { + WORD32 idx; + + WORD32 anal_size = ptr_hbe_txposer->analy_size; + + WORD32 N = (10 * ptr_hbe_txposer->analy_size); + + idx = 0; + while (idx < ptr_hbe_txposer->no_bins) { + WORD32 i, j, k, l; + FLOAT32 window_output[640] = {0}; + FLOAT32 u[128] = {0}; + FLOAT32 accu_r, accu_i; + const FLOAT32 *ptr_inp_signal; + FLOAT32 *ptr_qmf_buf_r = &qmf_buf_real[idx][ptr_hbe_txposer->a_start]; + FLOAT32 *ptr_qmf_buf_i = &qmf_buf_imag[idx][ptr_hbe_txposer->a_start]; + + const FLOAT32 *ptr_interp_window_coeff = ptr_hbe_txposer->ptr_ana_win_coeff; + FLOAT32 *ptr_x = ptr_hbe_txposer->analy_buf; + + memset(&qmf_buf_real[idx][ptr_hbe_txposer->a_start], 0, + (IXHEAACE_NUM_QMF_SYNTH_CHANNELS - ptr_hbe_txposer->a_start) * + sizeof(qmf_buf_real[idx][ptr_hbe_txposer->a_start])); + memset(&qmf_buf_imag[idx][ptr_hbe_txposer->a_start], 0, + IXHEAACE_TWICE_QMF_SYNTH_CH_NUM * sizeof(qmf_buf_imag[idx][ptr_hbe_txposer->a_start])); + + ptr_inp_signal = ptr_hbe_txposer->ptr_output_buf + idx * ptr_hbe_txposer->analy_size + 1; + + for (i = N - 1; i >= anal_size; i--) { + ptr_x[i] = ptr_x[i - anal_size]; + } + + for (i = anal_size - 1; i >= 0; i--) { + ptr_x[i] = ptr_inp_signal[anal_size - 1 - i]; + } + + for (i = 0; i < N; i++) { + window_output[i] = ptr_x[i] * ptr_interp_window_coeff[i]; + } + + for (i = 0; i < 2 * anal_size; i++) { + accu_r = 0.0; + for (j = 0; j < 5; j++) { + accu_r = accu_r + window_output[i + j * 2 * anal_size]; + } + u[i] = accu_r; + } + + for (k = 0; k < anal_size; k++) { + accu_r = 0; + accu_i = 0; + for (l = 0; l < 2 * anal_size; l++) { + accu_r = accu_r + u[l] * ptr_hbe_txposer->str_dft_hbe_anal_coeff.real[k][l]; + accu_i = accu_i + u[l] * ptr_hbe_txposer->str_dft_hbe_anal_coeff.imag[k][l]; + } + ptr_qmf_buf_r[k] = (FLOAT32)accu_r; + ptr_qmf_buf_i[k] = (FLOAT32)accu_i; + } + + idx++; + } +} diff --git a/encoder/ixheaace_sbr_hbe_trans.c b/encoder/ixheaace_sbr_hbe_trans.c index d3a1e46..2d2daf3 100644 --- a/encoder/ixheaace_sbr_hbe_trans.c +++ b/encoder/ixheaace_sbr_hbe_trans.c @@ -24,6 +24,7 @@ #include "ixheaac_type_def.h" #include "ixheaace_bitbuffer.h" +#include "iusace_tns_usac.h" #include "iusace_cnst.h" #include "ixheaace_sbr_def.h" @@ -32,7 +33,1505 @@ #include "ixheaac_error_standards.h" #include "ixheaace_error_codes.h" #include "ixheaac_constants.h" +#include "ixheaac_esbr_rom.h" +static FLOAT32 *ixheaace_map_prot_filter(WORD32 filt_length) { + switch (filt_length) { + case 4: + return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[0]; + break; + case 8: + return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[40]; + break; + case 12: + return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[120]; + break; + case 16: + return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[240]; + break; + case 20: + return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[400]; + break; + case 24: + return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[600]; + break; + case 32: + return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[840]; + break; + case 40: + return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[1160]; + break; + default: + return (FLOAT32 *)&ixheaac_sub_samp_qmf_window_coeff[0]; + } +} + +IA_ERRORCODE ixheaace_qmf_hbe_data_reinit(ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer) { + WORD32 synth_size, sfb, patch, stop_patch; + WORD32 upsamp_4_flag = 0; + + if (pstr_hbe_txposer != NULL) { + pstr_hbe_txposer->start_band = pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_LOW][0]; + pstr_hbe_txposer->end_band = + pstr_hbe_txposer + ->ptr_freq_band_tab[IXHEAACE_LOW][pstr_hbe_txposer->num_sf_bands[IXHEAACE_LOW]]; + + pstr_hbe_txposer->synth_size = 4 * ((pstr_hbe_txposer->start_band + 4) / 8 + 1); + pstr_hbe_txposer->k_start = ixheaac_start_subband2kL_tbl[pstr_hbe_txposer->start_band]; + + upsamp_4_flag = pstr_hbe_txposer->upsamp_4_flag; + pstr_hbe_txposer->esbr_hq = 0; + + if (upsamp_4_flag) { + if (pstr_hbe_txposer->k_start + pstr_hbe_txposer->synth_size > 16) + pstr_hbe_txposer->k_start = 16 - pstr_hbe_txposer->synth_size; + } else if (pstr_hbe_txposer->core_frame_length == 768) { + if (pstr_hbe_txposer->k_start + pstr_hbe_txposer->synth_size > 24) + pstr_hbe_txposer->k_start = 24 - pstr_hbe_txposer->synth_size; + } + memset(pstr_hbe_txposer->synth_buf, 0, sizeof(pstr_hbe_txposer->synth_buf)); + synth_size = pstr_hbe_txposer->synth_size; + pstr_hbe_txposer->synth_buf_offset = 18 * synth_size; + switch (synth_size) { + case 4: + pstr_hbe_txposer->ptr_syn_cos_tab = (FLOAT32 *)ixheaac_synth_cos_table_kl_4; + pstr_hbe_txposer->ptr_analy_cos_sin_tab = (FLOAT32 *)ixheaac_analy_cos_sin_table_kl_8; + pstr_hbe_txposer->ixheaace_real_synth_fft = &ixheaac_real_synth_fft_p2; + pstr_hbe_txposer->ixheaace_cmplx_anal_fft = &ixheaac_cmplx_anal_fft_p2; + break; + case 8: + pstr_hbe_txposer->ptr_syn_cos_tab = (FLOAT32 *)ixheaac_synth_cos_table_kl_8; + pstr_hbe_txposer->ptr_analy_cos_sin_tab = (FLOAT32 *)ixheaac_analy_cos_sin_table_kl_16; + pstr_hbe_txposer->ixheaace_real_synth_fft = &ixheaac_real_synth_fft_p2; + pstr_hbe_txposer->ixheaace_cmplx_anal_fft = &ixheaac_cmplx_anal_fft_p2; + break; + case 12: + pstr_hbe_txposer->ptr_syn_cos_tab = (FLOAT32 *)ixheaac_synth_cos_table_kl_12; + pstr_hbe_txposer->ptr_analy_cos_sin_tab = (FLOAT32 *)ixheaac_analy_cos_sin_table_kl_24; + pstr_hbe_txposer->ixheaace_real_synth_fft = &ixheaac_real_synth_fft_p3; + pstr_hbe_txposer->ixheaace_cmplx_anal_fft = &ixheaac_cmplx_anal_fft_p3; + break; + case 16: + pstr_hbe_txposer->ptr_syn_cos_tab = (FLOAT32 *)ixheaac_synth_cos_table_kl_16; + pstr_hbe_txposer->ptr_analy_cos_sin_tab = (FLOAT32 *)ixheaac_analy_cos_sin_table_kl_32; + pstr_hbe_txposer->ixheaace_real_synth_fft = &ixheaac_real_synth_fft_p2; + pstr_hbe_txposer->ixheaace_cmplx_anal_fft = &ixheaac_cmplx_anal_fft_p2; + break; + case 20: + pstr_hbe_txposer->ptr_syn_cos_tab = (FLOAT32 *)ixheaac_synth_cos_table_kl_20; + pstr_hbe_txposer->ptr_analy_cos_sin_tab = (FLOAT32 *)ixheaac_analy_cos_sin_table_kl_40; + break; + default: + pstr_hbe_txposer->ptr_syn_cos_tab = (FLOAT32 *)ixheaac_synth_cos_table_kl_4; + pstr_hbe_txposer->ptr_analy_cos_sin_tab = (FLOAT32 *)ixheaac_analy_cos_sin_table_kl_8; + pstr_hbe_txposer->ixheaace_real_synth_fft = &ixheaac_real_synth_fft_p2; + pstr_hbe_txposer->ixheaace_cmplx_anal_fft = &ixheaac_cmplx_anal_fft_p2; + } + + pstr_hbe_txposer->ptr_syn_win_coeff = ixheaace_map_prot_filter(synth_size); + + memset(pstr_hbe_txposer->analy_buf, 0, sizeof(pstr_hbe_txposer->analy_buf)); + synth_size = 2 * pstr_hbe_txposer->synth_size; + pstr_hbe_txposer->ptr_ana_win_coeff = ixheaace_map_prot_filter(synth_size); + + memset(pstr_hbe_txposer->x_over_qmf, 0, sizeof(pstr_hbe_txposer->x_over_qmf)); + sfb = 0; + if (upsamp_4_flag) { + stop_patch = IXHEAACE_MAX_NUM_PATCHES; + pstr_hbe_txposer->max_stretch = IXHEAACE_MAX_STRETCH; + } else { + stop_patch = IXHEAACE_MAX_STRETCH; + } + + for (patch = 1; patch <= stop_patch; patch++) { + while (sfb <= pstr_hbe_txposer->num_sf_bands[IXHEAACE_LOW] && + pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_LOW][sfb] <= + patch * pstr_hbe_txposer->start_band) + sfb++; + if (sfb <= pstr_hbe_txposer->num_sf_bands[IXHEAACE_LOW]) { + if ((patch * pstr_hbe_txposer->start_band - + pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_LOW][sfb - 1]) <= 3) { + pstr_hbe_txposer->x_over_qmf[patch - 1] = + pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_LOW][sfb - 1]; + } else { + WORD32 sfb_idx = 0; + while (sfb_idx <= pstr_hbe_txposer->num_sf_bands[IXHEAACE_HIGH] && + pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_HIGH][sfb_idx] <= + patch * pstr_hbe_txposer->start_band) + sfb_idx++; + pstr_hbe_txposer->x_over_qmf[patch - 1] = + pstr_hbe_txposer->ptr_freq_band_tab[IXHEAACE_HIGH][sfb_idx - 1]; + } + } else { + pstr_hbe_txposer->x_over_qmf[patch - 1] = pstr_hbe_txposer->end_band; + pstr_hbe_txposer->max_stretch = min(patch, IXHEAACE_MAX_STRETCH); + break; + } + } + if (pstr_hbe_txposer->k_start < 0) { + return IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_START_BAND; + } + } + return IA_NO_ERROR; +} + +IA_ERRORCODE ixheaace_qmf_hbe_apply(ixheaace_str_esbr_hbe_txposer *pstr_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) { + WORD32 i, qmf_band_idx; + WORD32 qmf_voc_columns = pstr_hbe_txposer->no_bins / 2; + WORD32 err_code = IA_NO_ERROR; + + memcpy( + pstr_hbe_txposer->ptr_input_buf, + pstr_hbe_txposer->ptr_input_buf + pstr_hbe_txposer->no_bins * pstr_hbe_txposer->synth_size, + pstr_hbe_txposer->synth_size * sizeof(pstr_hbe_txposer->ptr_input_buf[0])); + + if (pstr_hbe_txposer->ixheaace_cmplx_anal_fft == NULL) { + err_code = ixheaace_qmf_hbe_data_reinit(pstr_hbe_txposer); + if (err_code) { + return err_code; + } + } + + err_code = ixheaace_real_synth_filt(pstr_hbe_txposer, num_columns, qmf_buf_real, qmf_buf_imag); + if (err_code) { + return err_code; + } + + for (i = 0; i < IXHEAACE_HBE_OPER_WIN_LEN - 1; i++) { + memcpy(pstr_hbe_txposer->qmf_in_buf[i], pstr_hbe_txposer->qmf_in_buf[i + qmf_voc_columns], + sizeof(pstr_hbe_txposer->qmf_in_buf[i])); + } + + err_code = ixheaace_complex_anal_filt(pstr_hbe_txposer); + if (err_code) { + return err_code; + } + + for (i = 0; i < (pstr_hbe_txposer->hbe_qmf_out_len - pstr_hbe_txposer->no_bins); i++) { + memcpy(pstr_hbe_txposer->qmf_out_buf[i], + pstr_hbe_txposer->qmf_out_buf[i + pstr_hbe_txposer->no_bins], + sizeof(pstr_hbe_txposer->qmf_out_buf[i])); + } + + for (; i < pstr_hbe_txposer->hbe_qmf_out_len; i++) { + memset(pstr_hbe_txposer->qmf_out_buf[i], 0, sizeof(pstr_hbe_txposer->qmf_out_buf[i])); + } + + err_code = ixheaace_hbe_post_anal_process(pstr_hbe_txposer, pitch_in_bins, + pstr_hbe_txposer->upsamp_4_flag); + if (err_code) { + return err_code; + } + i = 0; + while (i < pstr_hbe_txposer->no_bins) { + for (qmf_band_idx = pstr_hbe_txposer->start_band; qmf_band_idx < pstr_hbe_txposer->end_band; + qmf_band_idx++) { + pv_qmf_buf_real[i][qmf_band_idx] = + (FLOAT32)(pstr_hbe_txposer->qmf_out_buf[i][2 * qmf_band_idx] * + ixheaac_phase_vocoder_cos_table[qmf_band_idx] - + pstr_hbe_txposer->qmf_out_buf[i][2 * qmf_band_idx + 1] * + ixheaac_phase_vocoder_sin_table[qmf_band_idx]); + + pv_qmf_buf_imag[i][qmf_band_idx] = + (FLOAT32)(pstr_hbe_txposer->qmf_out_buf[i][2 * qmf_band_idx] * + ixheaac_phase_vocoder_sin_table[qmf_band_idx] + + pstr_hbe_txposer->qmf_out_buf[i][2 * qmf_band_idx + 1] * + ixheaac_phase_vocoder_cos_table[qmf_band_idx]); + } + i++; + } + return err_code; +} + +VOID ixheaace_norm_qmf_in_buf_4(ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer, + WORD32 qmf_band_idx) { + WORD32 i; + FLOAT32 *ptr_in_buf = &pstr_hbe_txposer->qmf_in_buf[0][2 * qmf_band_idx]; + FLOAT32 *ptr_norm_buf = &pstr_hbe_txposer->norm_qmf_in_buf[0][2 * qmf_band_idx]; + + for (; qmf_band_idx <= pstr_hbe_txposer->x_over_qmf[3]; qmf_band_idx++) { + for (i = 0; i < pstr_hbe_txposer->hbe_qmf_in_len; i++) { + FLOAT32 mag_scaling_fac = 0.0f; + FLOAT32 x_r, x_i, temp; + FLOAT64 base = 1e-17; + x_r = ptr_in_buf[0]; + x_i = ptr_in_buf[1]; + + temp = x_r * x_r; + base = base + temp; + temp = x_i * x_i; + base = base + temp; + + temp = (FLOAT32)sqrt(sqrt(base)); + mag_scaling_fac = temp * (FLOAT32)(sqrt(temp)); + + mag_scaling_fac = 1 / mag_scaling_fac; + + x_r *= mag_scaling_fac; + x_i *= mag_scaling_fac; + + ptr_norm_buf[0] = x_r; + ptr_norm_buf[1] = x_i; + + ptr_in_buf += 128; + ptr_norm_buf += 128; + } + + ptr_in_buf -= (128 * (pstr_hbe_txposer->hbe_qmf_in_len) - 2); + ptr_norm_buf -= (128 * (pstr_hbe_txposer->hbe_qmf_in_len) - 2); + } +} + +VOID ixheaace_norm_qmf_in_buf_2(ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer, + WORD32 qmf_band_idx) { + WORD32 i; + FLOAT32 *ptr_in_buf = &pstr_hbe_txposer->qmf_in_buf[0][2 * qmf_band_idx]; + FLOAT32 *ptr_norm_buf = &pstr_hbe_txposer->norm_qmf_in_buf[0][2 * qmf_band_idx]; + + for (; qmf_band_idx <= pstr_hbe_txposer->x_over_qmf[1]; qmf_band_idx++) { + for (i = 0; i < pstr_hbe_txposer->hbe_qmf_in_len; i++) { + FLOAT32 mag_scaling_fac = 0.0f; + FLOAT32 x_r, x_i, temp; + FLOAT64 base = 1e-17; + x_r = ptr_in_buf[0]; + x_i = ptr_in_buf[1]; + + temp = x_r * x_r; + base = base + temp; + base = base + x_i * x_i; + + mag_scaling_fac = (FLOAT32)(1.0f / base); + mag_scaling_fac = (FLOAT32)sqrt(sqrt(mag_scaling_fac)); + + x_r *= mag_scaling_fac; + x_i *= mag_scaling_fac; + + ptr_norm_buf[0] = x_r; + ptr_norm_buf[1] = x_i; + + ptr_in_buf += 128; + ptr_norm_buf += 128; + } + + ptr_in_buf -= (128 * (pstr_hbe_txposer->hbe_qmf_in_len) - 2); + ptr_norm_buf -= (128 * (pstr_hbe_txposer->hbe_qmf_in_len) - 2); + } +} + +VOID ixheaace_hbe_xprod_proc_3(ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer, + WORD32 qmf_band_idx, WORD32 qmf_col_idx, FLOAT32 p, + WORD32 pitch_in_bins_idx) { + WORD32 tr, n1, n2, max_trans_fac, max_n1, max_n2; + WORD32 k, addrshift; + WORD32 inp_band_idx = 2 * qmf_band_idx / 3; + + FLOAT64 temp_fac; + FLOAT32 max_mag_value; + FLOAT32 mag_zero_band, mag_n1_band, mag_n2_band, temp; + FLOAT32 temp_r, temp_i; + FLOAT32 mag_cmplx_gain = 1.8856f; + + FLOAT32 *ptr_qmf_in_buf_ri = + pstr_hbe_txposer->qmf_in_buf[qmf_col_idx + IXHEAACE_HBE_ZERO_BAND_IDX]; + + mag_zero_band = + ptr_qmf_in_buf_ri[2 * inp_band_idx] * ptr_qmf_in_buf_ri[2 * inp_band_idx] + + ptr_qmf_in_buf_ri[2 * inp_band_idx + 1] * ptr_qmf_in_buf_ri[2 * inp_band_idx + 1]; + max_mag_value = 0; + max_n1 = max_n2 = max_trans_fac = 0; + + for (tr = 1; tr < 3; tr++) { + temp_fac = (2.0f * qmf_band_idx + 1 - tr * p) * 0.3333334; + + n1 = (WORD32)(temp_fac); + n2 = (WORD32)(temp_fac + p); + + mag_n1_band = ptr_qmf_in_buf_ri[2 * n1] * ptr_qmf_in_buf_ri[2 * n1] + + ptr_qmf_in_buf_ri[2 * n1 + 1] * ptr_qmf_in_buf_ri[2 * n1 + 1]; + mag_n2_band = ptr_qmf_in_buf_ri[2 * n2] * ptr_qmf_in_buf_ri[2 * n2] + + ptr_qmf_in_buf_ri[2 * n2 + 1] * ptr_qmf_in_buf_ri[2 * n2 + 1]; + temp = min(mag_n1_band, mag_n2_band); + + if (temp > max_mag_value) { + max_mag_value = temp; + max_trans_fac = tr; + max_n1 = n1; + max_n2 = n2; + } + } + + if ((max_mag_value > mag_zero_band && max_n1 >= 0) && + (max_n2 < IXHEAACE_NUM_QMF_SYNTH_CHANNELS)) { + FLOAT32 vec_y_r[2], vec_y_i[2], vec_o_r[2], vec_o_i[2]; + FLOAT32 coeff_real[2], coeff_imag[2]; + FLOAT32 d1, d2; + WORD32 mid_trans_fac, idx; + FLOAT64 base = 1e-17; + FLOAT32 mag_scaling_fac = 0; + FLOAT32 x_zero_band_r; + FLOAT32 x_zero_band_i; + + mid_trans_fac = 3 - max_trans_fac; + if (max_trans_fac == 1) { + d1 = 0; + d2 = 1.5; + x_zero_band_r = ptr_qmf_in_buf_ri[2 * max_n1]; + x_zero_band_i = ptr_qmf_in_buf_ri[2 * max_n1 + 1]; + + idx = max_n2 & 3; + idx = (idx + 1) & 3; + coeff_real[0] = ixheaac_hbe_post_anal_proc_interp_coeff[idx][0]; + coeff_imag[0] = ixheaac_hbe_post_anal_proc_interp_coeff[idx][1]; + + coeff_real[1] = coeff_real[0]; + coeff_imag[1] = -coeff_imag[0]; + + vec_y_r[1] = ptr_qmf_in_buf_ri[2 * max_n2]; + vec_y_i[1] = ptr_qmf_in_buf_ri[2 * max_n2 + 1]; + + addrshift = -2; + temp_r = pstr_hbe_txposer + ->qmf_in_buf[qmf_col_idx + addrshift + IXHEAACE_HBE_ZERO_BAND_IDX][2 * max_n2]; + temp_i = + pstr_hbe_txposer + ->qmf_in_buf[qmf_col_idx + addrshift + IXHEAACE_HBE_ZERO_BAND_IDX][2 * max_n2 + 1]; + + vec_y_r[0] = coeff_real[1] * temp_r - coeff_imag[1] * temp_i; + vec_y_i[0] = coeff_imag[1] * temp_r + coeff_real[1] * temp_i; + + temp_r = + pstr_hbe_txposer + ->qmf_in_buf[qmf_col_idx + addrshift + 1 + IXHEAACE_HBE_ZERO_BAND_IDX][2 * max_n2]; + temp_i = pstr_hbe_txposer->qmf_in_buf[qmf_col_idx + addrshift + 1 + + IXHEAACE_HBE_ZERO_BAND_IDX][2 * max_n2 + 1]; + + vec_y_r[0] += coeff_real[0] * temp_r - coeff_imag[0] * temp_i; + vec_y_i[0] += coeff_imag[0] * temp_r + coeff_real[0] * temp_i; + } else { + d1 = 1.5; + d2 = 0; + mid_trans_fac = max_trans_fac; + max_trans_fac = 3 - max_trans_fac; + + x_zero_band_r = ptr_qmf_in_buf_ri[2 * max_n2]; + x_zero_band_i = ptr_qmf_in_buf_ri[2 * max_n2 + 1]; + + idx = (max_n1 & 3); + idx = (idx + 1) & 3; + coeff_real[0] = ixheaac_hbe_post_anal_proc_interp_coeff[idx][0]; + coeff_imag[0] = ixheaac_hbe_post_anal_proc_interp_coeff[idx][1]; + + coeff_real[1] = coeff_real[0]; + coeff_imag[1] = -coeff_imag[0]; + + vec_y_r[1] = ptr_qmf_in_buf_ri[2 * max_n1]; + vec_y_i[1] = ptr_qmf_in_buf_ri[2 * max_n1 + 1]; + + addrshift = -2; + + temp_r = pstr_hbe_txposer + ->qmf_in_buf[qmf_col_idx + addrshift + IXHEAACE_HBE_ZERO_BAND_IDX][2 * max_n1]; + temp_i = + pstr_hbe_txposer + ->qmf_in_buf[qmf_col_idx + addrshift + IXHEAACE_HBE_ZERO_BAND_IDX][2 * max_n1 + 1]; + + vec_y_r[0] = coeff_real[1] * temp_r - coeff_imag[1] * temp_i; + vec_y_i[0] = coeff_imag[1] * temp_r + coeff_real[1] * temp_i; + + temp_r = + pstr_hbe_txposer + ->qmf_in_buf[qmf_col_idx + addrshift + 1 + IXHEAACE_HBE_ZERO_BAND_IDX][2 * max_n1]; + temp_i = pstr_hbe_txposer->qmf_in_buf[qmf_col_idx + addrshift + 1 + + IXHEAACE_HBE_ZERO_BAND_IDX][2 * max_n1 + 1]; + + vec_y_r[0] += coeff_real[0] * temp_r - coeff_imag[0] * temp_i; + vec_y_i[0] += coeff_imag[0] * temp_r + coeff_real[0] * temp_i; + } + + base = 1e-17; + base = base + x_zero_band_r * x_zero_band_r; + base = base + x_zero_band_i * x_zero_band_i; + mag_scaling_fac = (FLOAT32)(ixheaace_cbrt_calc((FLOAT32)base)); + x_zero_band_r *= mag_scaling_fac; + x_zero_band_i *= mag_scaling_fac; + for (k = 0; k < 2; k++) { + base = 1e-17; + base = base + vec_y_r[k] * vec_y_r[k]; + base = base + vec_y_i[k] * vec_y_i[k]; + mag_scaling_fac = (FLOAT32)(ixheaace_cbrt_calc((FLOAT32)base)); + vec_y_r[k] *= mag_scaling_fac; + vec_y_i[k] *= mag_scaling_fac; + } + + temp_r = x_zero_band_r; + temp_i = x_zero_band_i; + for (idx = 0; idx < mid_trans_fac - 1; idx++) { + FLOAT32 tmp = x_zero_band_r; + x_zero_band_r = x_zero_band_r * temp_r - x_zero_band_i * temp_i; + x_zero_band_i = tmp * temp_i + x_zero_band_i * temp_r; + } + + for (k = 0; k < 2; k++) { + temp_r = vec_y_r[k]; + temp_i = vec_y_i[k]; + for (idx = 0; idx < max_trans_fac - 1; idx++) { + FLOAT32 tmp = vec_y_r[k]; + vec_y_r[k] = vec_y_r[k] * temp_r - vec_y_i[k] * temp_i; + vec_y_i[k] = tmp * temp_i + vec_y_i[k] * temp_r; + } + } + + for (k = 0; k < 2; k++) { + vec_o_r[k] = vec_y_r[k] * x_zero_band_r - vec_y_i[k] * x_zero_band_i; + vec_o_i[k] = vec_y_r[k] * x_zero_band_i + vec_y_i[k] * x_zero_band_r; + } + + { + FLOAT32 cos_theta = ixheaac_hbe_x_prod_cos_table_trans_3[(pitch_in_bins_idx << 1) + 0]; + FLOAT32 sin_theta = ixheaac_hbe_x_prod_cos_table_trans_3[(pitch_in_bins_idx << 1) + 1]; + if (d2 < d1) { + sin_theta = -sin_theta; + } + temp_r = vec_o_r[0]; + temp_i = vec_o_i[0]; + vec_o_r[0] = (FLOAT32)(cos_theta * temp_r - sin_theta * temp_i); + vec_o_i[0] = (FLOAT32)(cos_theta * temp_i + sin_theta * temp_r); + } + + for (k = 0; k < 2; k++) { + pstr_hbe_txposer->qmf_out_buf[qmf_col_idx * 2 + (k + IXHEAACE_HBE_ZERO_BAND_IDX - 1)] + [2 * qmf_band_idx] += (FLOAT32)(mag_cmplx_gain * vec_o_r[k]); + pstr_hbe_txposer->qmf_out_buf[qmf_col_idx * 2 + (k + IXHEAACE_HBE_ZERO_BAND_IDX - 1)] + [2 * qmf_band_idx + 1] += + (FLOAT32)(mag_cmplx_gain * vec_o_i[k]); + } + } +} + +VOID ixheaace_hbe_xprod_proc_4(ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer, + WORD32 qmf_band_idx, WORD32 qmf_col_idx, FLOAT32 p, + WORD32 pitch_in_bins_idx) { + WORD32 k; + WORD32 inp_band_idx = qmf_band_idx >> 1; + WORD32 tr, n1, n2, max_trans_fac, max_n1, max_n2; + + FLOAT64 temp_fac; + FLOAT32 max_mag_value, mag_zero_band, mag_n1_band, mag_n2_band, temp; + FLOAT32 temp_r, temp_i; + FLOAT32 mag_cmplx_gain = 2.0f; + + FLOAT32 *ptr_qmf_in_buf_ri = + pstr_hbe_txposer->qmf_in_buf[qmf_col_idx + IXHEAACE_HBE_ZERO_BAND_IDX]; + + mag_zero_band = + ptr_qmf_in_buf_ri[2 * inp_band_idx] * ptr_qmf_in_buf_ri[2 * inp_band_idx] + + ptr_qmf_in_buf_ri[2 * inp_band_idx + 1] * ptr_qmf_in_buf_ri[2 * inp_band_idx + 1]; + + max_mag_value = 0; + max_n1 = max_n2 = max_trans_fac = 0; + + tr = 1; + while (tr < 4) { + temp_fac = (2.0 * qmf_band_idx + 1 - tr * p) * 0.25; + n1 = ((WORD32)(temp_fac)) << 1; + n2 = ((WORD32)(temp_fac + p)) << 1; + + mag_n1_band = ptr_qmf_in_buf_ri[n1] * ptr_qmf_in_buf_ri[n1] + + ptr_qmf_in_buf_ri[n1 + 1] * ptr_qmf_in_buf_ri[n1 + 1]; + mag_n2_band = ptr_qmf_in_buf_ri[n2] * ptr_qmf_in_buf_ri[n2] + + ptr_qmf_in_buf_ri[n2 + 1] * ptr_qmf_in_buf_ri[n2 + 1]; + + temp = min(mag_n1_band, mag_n2_band); + + if (temp > max_mag_value) { + max_mag_value = temp; + max_trans_fac = tr; + max_n1 = n1; + max_n2 = n2; + } + tr++; + } + if (max_mag_value > mag_zero_band && max_n1 >= 0 && max_n2 < IXHEAACE_TWICE_QMF_SYNTH_CH_NUM) { + FLOAT32 vec_y_r[2], vec_y_i[2], vec_o_r[2], vec_o_i[2]; + FLOAT32 d1, d2; + WORD32 mid_trans_fac, idx; + FLOAT32 x_zero_band_r; + FLOAT32 x_zero_band_i; + FLOAT64 base = 1e-17; + FLOAT32 mag_scaling_fac = 0.0f; + + mid_trans_fac = 4 - max_trans_fac; + + if (max_trans_fac == 1) { + d1 = 0; + d2 = 2; + x_zero_band_r = ptr_qmf_in_buf_ri[max_n1]; + x_zero_band_i = ptr_qmf_in_buf_ri[max_n1 + 1]; + for (k = 0; k < 2; k++) { + vec_y_r[k] = + pstr_hbe_txposer + ->qmf_in_buf[qmf_col_idx + IXHEAACE_HBE_ZERO_BAND_IDX + 2 * (k - 1)][max_n2]; + vec_y_i[k] = + pstr_hbe_txposer + ->qmf_in_buf[qmf_col_idx + IXHEAACE_HBE_ZERO_BAND_IDX + 2 * (k - 1)][max_n2 + 1]; + } + } else if (max_trans_fac == 2) { + d1 = 0; + d2 = 1; + x_zero_band_r = ptr_qmf_in_buf_ri[max_n1]; + x_zero_band_i = ptr_qmf_in_buf_ri[max_n1 + 1]; + for (k = 0; k < 2; k++) { + vec_y_r[k] = pstr_hbe_txposer + ->qmf_in_buf[qmf_col_idx + IXHEAACE_HBE_ZERO_BAND_IDX + (k - 1)][max_n2]; + vec_y_i[k] = + pstr_hbe_txposer + ->qmf_in_buf[qmf_col_idx + IXHEAACE_HBE_ZERO_BAND_IDX + (k - 1)][max_n2 + 1]; + } + } else { + d1 = 2; + d2 = 0; + mid_trans_fac = max_trans_fac; + max_trans_fac = 4 - max_trans_fac; + x_zero_band_r = ptr_qmf_in_buf_ri[max_n2]; + x_zero_band_i = ptr_qmf_in_buf_ri[max_n2 + 1]; + for (k = 0; k < 2; k++) { + vec_y_r[k] = + pstr_hbe_txposer + ->qmf_in_buf[qmf_col_idx + IXHEAACE_HBE_ZERO_BAND_IDX + 2 * (k - 1)][max_n1]; + vec_y_i[k] = + pstr_hbe_txposer + ->qmf_in_buf[qmf_col_idx + IXHEAACE_HBE_ZERO_BAND_IDX + 2 * (k - 1)][max_n1 + 1]; + } + } + + base = 1e-17; + base = base + x_zero_band_r * x_zero_band_r; + base = base + x_zero_band_i * x_zero_band_i; + { + temp = (FLOAT32)sqrt(sqrt(base)); + mag_scaling_fac = temp * (FLOAT32)(sqrt(temp)); + mag_scaling_fac = 1 / mag_scaling_fac; + } + + x_zero_band_r *= mag_scaling_fac; + x_zero_band_i *= mag_scaling_fac; + for (k = 0; k < 2; k++) { + base = 1e-17; + base = base + vec_y_r[k] * vec_y_r[k]; + base = base + vec_y_i[k] * vec_y_i[k]; + { + temp = (FLOAT32)sqrt(sqrt(base)); + mag_scaling_fac = temp * (FLOAT32)(sqrt(temp)); + + mag_scaling_fac = 1 / mag_scaling_fac; + } + vec_y_r[k] *= mag_scaling_fac; + vec_y_i[k] *= mag_scaling_fac; + } + + temp_r = x_zero_band_r; + temp_i = x_zero_band_i; + for (idx = 0; idx < mid_trans_fac - 1; idx++) { + FLOAT32 tmp = x_zero_band_r; + x_zero_band_r = x_zero_band_r * temp_r - x_zero_band_i * temp_i; + x_zero_band_i = tmp * temp_i + x_zero_band_i * temp_r; + } + + for (k = 0; k < 2; k++) { + temp_r = vec_y_r[k]; + temp_i = vec_y_i[k]; + for (idx = 0; idx < max_trans_fac - 1; idx++) { + FLOAT32 tmp = vec_y_r[k]; + vec_y_r[k] = vec_y_r[k] * temp_r - vec_y_i[k] * temp_i; + vec_y_i[k] = tmp * temp_i + vec_y_i[k] * temp_r; + } + } + + for (k = 0; k < 2; k++) { + vec_o_r[k] = vec_y_r[k] * x_zero_band_r - vec_y_i[k] * x_zero_band_i; + vec_o_i[k] = vec_y_r[k] * x_zero_band_i + vec_y_i[k] * x_zero_band_r; + } + + { + FLOAT32 cos_theta; + FLOAT32 sin_theta; + + if (d2 == 1) { + cos_theta = ixheaac_hbe_x_prod_cos_table_trans_4_1[(pitch_in_bins_idx << 1) + 0]; + sin_theta = ixheaac_hbe_x_prod_cos_table_trans_4_1[(pitch_in_bins_idx << 1) + 1]; + } else { + cos_theta = ixheaac_hbe_x_prod_cos_table_trans_4[(pitch_in_bins_idx << 1) + 0]; + sin_theta = ixheaac_hbe_x_prod_cos_table_trans_4[(pitch_in_bins_idx << 1) + 1]; + if (d2 < d1) { + sin_theta = -sin_theta; + } + } + temp_r = vec_o_r[0]; + temp_i = vec_o_i[0]; + vec_o_r[0] = (FLOAT32)(cos_theta * temp_r - sin_theta * temp_i); + vec_o_i[0] = (FLOAT32)(cos_theta * temp_i + sin_theta * temp_r); + } + + for (k = 0; k < 2; k++) { + pstr_hbe_txposer->qmf_out_buf[qmf_col_idx * 2 + (k + IXHEAACE_HBE_ZERO_BAND_IDX - 1)] + [2 * qmf_band_idx] += (FLOAT32)(mag_cmplx_gain * vec_o_r[k]); + pstr_hbe_txposer->qmf_out_buf[qmf_col_idx * 2 + (k + IXHEAACE_HBE_ZERO_BAND_IDX - 1)] + [2 * qmf_band_idx + 1] += + (FLOAT32)(mag_cmplx_gain * vec_o_i[k]); + } + } +} + +VOID ixheaace_hbe_post_anal_prod2(ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer, + WORD32 qmf_voc_columns, WORD32 qmf_band_idx) { + WORD32 i; + FLOAT32 *ptr_norm = &pstr_hbe_txposer->norm_qmf_in_buf[1][2 * qmf_band_idx]; + FLOAT32 *ptr_out = &pstr_hbe_txposer->qmf_out_buf[1][2 * qmf_band_idx]; + FLOAT32 *ptr_x_norm = + &pstr_hbe_txposer->norm_qmf_in_buf[IXHEAACE_HBE_ZERO_BAND_IDX][2 * qmf_band_idx]; + + ixheaace_norm_qmf_in_buf_2(pstr_hbe_txposer, qmf_band_idx); + + for (; qmf_band_idx < pstr_hbe_txposer->x_over_qmf[1]; qmf_band_idx++) { + for (i = 0; i < qmf_voc_columns; i++) { + WORD32 k; + FLOAT32 x_zero_band_r, x_zero_band_i; + + x_zero_band_r = *ptr_x_norm++; + x_zero_band_i = *ptr_x_norm++; + + for (k = 0; k < IXHEAACE_HBE_OPER_BLK_LEN_2; k++) { + register FLOAT32 tmp_r, tmp_i; + tmp_r = *ptr_norm++; + tmp_i = *ptr_norm++; + + *ptr_out++ += ((tmp_r * x_zero_band_r - tmp_i * x_zero_band_i) * 0.3333333f); + + *ptr_out++ += ((tmp_r * x_zero_band_i + tmp_i * x_zero_band_r) * 0.3333333f); + + ptr_norm += 126; + ptr_out += 126; + } + + ptr_norm -= 128 * 9; + ptr_out -= 128 * 8; + ptr_x_norm += 126; + } + ptr_out -= (128 * 2 * qmf_voc_columns) - 2; + ptr_norm -= (128 * qmf_voc_columns) - 2; + ptr_x_norm -= (128 * qmf_voc_columns) - 2; + } +} + +VOID ixheaace_hbe_post_anal_prod3(ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer, + WORD32 qmf_voc_columns, WORD32 qmf_band_idx) { + WORD32 i, inp_band_idx, rem; + + FLOAT32 *ptr_out_buf = &pstr_hbe_txposer->qmf_out_buf[2][2 * qmf_band_idx]; + + for (; qmf_band_idx < pstr_hbe_txposer->x_over_qmf[2]; qmf_band_idx++) { + FLOAT32 temp_r, temp_i; + FLOAT32 temp_r1, temp_i1; + const FLOAT32 *ptr_sel, *ptr_sel1; + + inp_band_idx = (2 * qmf_band_idx) / 3; + ptr_sel = &ixheaac_sel_case[(inp_band_idx + 1) & 3][0]; + ptr_sel1 = &ixheaac_sel_case[((inp_band_idx + 1) & 3) + 1][0]; + rem = 2 * qmf_band_idx - 3 * inp_band_idx; + + if (rem == 0 || rem == 1) { + FLOAT32 *ptr_in_buf = &pstr_hbe_txposer->qmf_in_buf[0][2 * inp_band_idx]; + + for (i = 0; i < qmf_voc_columns; i += 1) { + WORD32 k; + FLOAT32 vec_x[2 * IXHEAACE_HBE_OPER_WIN_LEN]; + FLOAT32 *ptr_vec_x = &vec_x[0]; + FLOAT32 x_zero_band_r, x_zero_band_i; + + FLOAT32 mag_scaling_fac; + + for (k = 0; k < (IXHEAACE_HBE_OPER_BLK_LEN_3); k += 2) { + FLOAT64 base1; + FLOAT64 base = 1e-17; + + temp_r = ptr_in_buf[0]; + temp_i = ptr_in_buf[1]; + + ptr_in_buf += 256; + + base1 = base + temp_r * temp_r; + base1 = base1 + temp_i * temp_i; + + mag_scaling_fac = (FLOAT32)(ixheaace_cbrt_calc((FLOAT32)base1)); + + ptr_vec_x[0] = temp_r * mag_scaling_fac; + ptr_vec_x[1] = temp_i * mag_scaling_fac; + + temp_r = ptr_in_buf[0]; + temp_i = ptr_in_buf[1]; + + ptr_in_buf -= 128; + + temp_r1 = ptr_sel[0] * temp_r + ptr_sel[1] * temp_i; + temp_i1 = ptr_sel[2] * temp_r + ptr_sel[3] * temp_i; + + temp_r = ptr_in_buf[0]; + temp_i = ptr_in_buf[1]; + + temp_r1 += ptr_sel[4] * temp_r + ptr_sel[5] * temp_i; + temp_i1 += ptr_sel[6] * temp_r + ptr_sel[7] * temp_i; + + temp_r1 *= 0.3984033437f; + temp_i1 *= 0.3984033437f; + + base1 = base + temp_r1 * temp_r1; + base1 = base1 + temp_i1 * temp_i1; + mag_scaling_fac = (FLOAT32)(ixheaace_cbrt_calc((FLOAT32)base1)); + + ptr_vec_x[2] = temp_r1 * mag_scaling_fac; + ptr_vec_x[3] = temp_i1 * mag_scaling_fac; + + ptr_vec_x += 4; + ptr_in_buf += 256; + } + ptr_vec_x = &vec_x[0]; + temp_r = vec_x[2 * (IXHEAACE_HBE_ZERO_BAND_IDX - 2)]; + temp_i = vec_x[(2 * (IXHEAACE_HBE_ZERO_BAND_IDX - 2)) + 1]; + + x_zero_band_r = temp_r * temp_r - temp_i * temp_i; + x_zero_band_i = temp_r * temp_i + temp_i * temp_r; + + for (k = 0; k < (IXHEAACE_HBE_OPER_BLK_LEN_3); k++) { + temp_r = ptr_vec_x[0] * x_zero_band_r - ptr_vec_x[1] * x_zero_band_i; + temp_i = ptr_vec_x[0] * x_zero_band_i + ptr_vec_x[1] * x_zero_band_r; + + ptr_out_buf[0] += (temp_r * 0.4714045f); + ptr_out_buf[1] += (temp_i * 0.4714045f); + + ptr_vec_x += 2; + ptr_out_buf += 128; + } + + ptr_in_buf -= 128 * 11; + ptr_out_buf -= 128 * 6; + } + } else { + FLOAT32 *ptr_in_buf = &pstr_hbe_txposer->qmf_in_buf[0][2 * inp_band_idx]; + FLOAT32 *ptr_in_buf1 = &pstr_hbe_txposer->qmf_in_buf[0][2 * (inp_band_idx + 1)]; + + for (i = 0; i < qmf_voc_columns; i++) { + WORD32 k; + FLOAT32 vec_x[2 * IXHEAACE_HBE_OPER_WIN_LEN]; + FLOAT32 vec_x_cap[2 * IXHEAACE_HBE_OPER_WIN_LEN]; + + FLOAT32 x_zero_band_r, x_zero_band_i; + FLOAT32 *ptr_vec_x = &vec_x[0]; + FLOAT32 *ptr_vec_x_cap = &vec_x_cap[0]; + + FLOAT32 mag_scaling_fac; + + for (k = 0; k < (IXHEAACE_HBE_OPER_BLK_LEN_3); k += 2) { + FLOAT32 tmp_vr, tmp_vi; + FLOAT32 tmp_cr, tmp_ci; + FLOAT64 base1; + FLOAT64 base = 1e-17; + + temp_r1 = ptr_in_buf[0]; + temp_i1 = ptr_in_buf[1]; + temp_r = ptr_in_buf1[0]; + temp_i = ptr_in_buf1[1]; + + base1 = base + temp_r * temp_r; + base1 = base1 + temp_i * temp_i; + + mag_scaling_fac = (FLOAT32)(ixheaace_cbrt_calc((FLOAT32)base1)); + + ptr_vec_x[0] = temp_r * mag_scaling_fac; + ptr_vec_x[1] = temp_i * mag_scaling_fac; + + base1 = base + temp_r1 * temp_r1; + base1 = base1 + temp_i1 * temp_i1; + + mag_scaling_fac = (FLOAT32)(ixheaace_cbrt_calc((FLOAT32)base1)); + + ptr_vec_x_cap[0] = temp_r1 * mag_scaling_fac; + ptr_vec_x_cap[1] = temp_i1 * mag_scaling_fac; + + ptr_in_buf += 256; + + temp_r = ptr_in_buf[0]; + temp_i = ptr_in_buf[1]; + + temp_r1 = ptr_sel[0] * temp_r + ptr_sel[1] * temp_i; + temp_i1 = ptr_sel[2] * temp_r + ptr_sel[3] * temp_i; + + ptr_in_buf -= 128; + + temp_r = ptr_in_buf[0]; + temp_i = ptr_in_buf[1]; + + tmp_cr = temp_r1 + ptr_sel[4] * temp_r + ptr_sel[5] * temp_i; + tmp_ci = temp_i1 + ptr_sel[6] * temp_r + ptr_sel[7] * temp_i; + + ptr_in_buf1 += 256; + + temp_r = ptr_in_buf1[0]; + temp_i = ptr_in_buf1[1]; + + temp_r1 = ptr_sel1[0] * temp_r + ptr_sel1[1] * temp_i; + temp_i1 = ptr_sel1[2] * temp_r + ptr_sel1[3] * temp_i; + + ptr_in_buf1 -= 128; + + temp_r = ptr_in_buf1[0]; + temp_i = ptr_in_buf1[1]; + + tmp_vr = temp_r1 + ptr_sel1[4] * temp_r + ptr_sel1[5] * temp_i; + tmp_vi = temp_i1 + ptr_sel1[6] * temp_r + ptr_sel1[7] * temp_i; + + tmp_cr *= 0.3984033437f; + tmp_ci *= 0.3984033437f; + + tmp_vr *= 0.3984033437f; + tmp_vi *= 0.3984033437f; + + base1 = base + tmp_vr * tmp_vr; + base1 = base1 + tmp_vi * tmp_vi; + + mag_scaling_fac = (FLOAT32)(ixheaace_cbrt_calc((FLOAT32)base1)); + + ptr_vec_x[2] = tmp_vr * mag_scaling_fac; + ptr_vec_x[3] = tmp_vi * mag_scaling_fac; + + base1 = base + tmp_cr * tmp_cr; + base1 = base1 + tmp_ci * tmp_ci; + + mag_scaling_fac = (FLOAT32)(ixheaace_cbrt_calc((FLOAT32)base1)); + + ptr_vec_x_cap[2] = tmp_cr * mag_scaling_fac; + ptr_vec_x_cap[3] = tmp_ci * mag_scaling_fac; + + ptr_in_buf += 256; + ptr_in_buf1 += 256; + ptr_vec_x += 4; + ptr_vec_x_cap += 4; + } + ptr_vec_x = &vec_x[0]; + ptr_vec_x_cap = &vec_x_cap[0]; + + temp_r = vec_x_cap[2 * (IXHEAACE_HBE_ZERO_BAND_IDX - 2)]; + temp_i = vec_x_cap[2 * (IXHEAACE_HBE_ZERO_BAND_IDX - 2) + 1]; + temp_r1 = vec_x[2 * (IXHEAACE_HBE_ZERO_BAND_IDX - 2)]; + temp_i1 = vec_x[2 * (IXHEAACE_HBE_ZERO_BAND_IDX - 2) + 1]; + + x_zero_band_r = temp_r * temp_r - temp_i * temp_i; + x_zero_band_i = temp_r * temp_i + temp_i * temp_r; + + temp_r = temp_r1 * temp_r1 - temp_i1 * temp_i1; + temp_i = temp_r1 * temp_i1 + temp_i1 * temp_r1; + + k = 0; + while (k < (IXHEAACE_HBE_OPER_BLK_LEN_3)) { + temp_r1 = ptr_vec_x[0] * x_zero_band_r - ptr_vec_x[1] * x_zero_band_i; + temp_i1 = ptr_vec_x[0] * x_zero_band_i + ptr_vec_x[1] * x_zero_band_r; + + temp_r1 += ptr_vec_x_cap[0] * temp_r - ptr_vec_x_cap[1] * temp_i; + temp_i1 += ptr_vec_x_cap[0] * temp_i + ptr_vec_x_cap[1] * temp_r; + + ptr_out_buf[0] += (temp_r1 * 0.23570225f); + ptr_out_buf[1] += (temp_i1 * 0.23570225f); + + ptr_out_buf += 128; + ptr_vec_x += 2; + ptr_vec_x_cap += 2; + + k++; + } + + ptr_in_buf -= 128 * 11; + ptr_in_buf1 -= 128 * 11; + ptr_out_buf -= 128 * 6; + } + } + + ptr_out_buf -= (256 * qmf_voc_columns) - 2; + } +} + +VOID ixheaace_hbe_post_anal_prod4(ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer, + WORD32 qmf_voc_columns, WORD32 qmf_band_idx) { + WORD32 i, inp_band_idx; + FLOAT32 *ptr_out = &pstr_hbe_txposer->qmf_out_buf[3][2 * qmf_band_idx]; + + ixheaace_norm_qmf_in_buf_4(pstr_hbe_txposer, ((qmf_band_idx >> 1) - 1)); + + for (; qmf_band_idx < pstr_hbe_txposer->x_over_qmf[3]; qmf_band_idx++) { + WORD32 ip_idx; + FLOAT32 temp, temp_r, temp_i; + FLOAT32 *ptr_norm, *ptr_x_norm; + inp_band_idx = qmf_band_idx >> 1; + ip_idx = (qmf_band_idx & 1) ? (inp_band_idx + 1) : (inp_band_idx - 1); + + ptr_norm = &pstr_hbe_txposer->norm_qmf_in_buf[0][2 * ip_idx]; + ptr_x_norm = &pstr_hbe_txposer->norm_qmf_in_buf[IXHEAACE_HBE_ZERO_BAND_IDX][2 * inp_band_idx]; + + i = 0; + while (i < qmf_voc_columns) { + WORD32 k; + FLOAT32 x_zero_band_r, x_zero_band_i; + + temp_r = x_zero_band_r = *ptr_x_norm++; + temp_i = x_zero_band_i = *ptr_x_norm++; + + temp = x_zero_band_r * x_zero_band_r - x_zero_band_i * x_zero_band_i; + x_zero_band_i = x_zero_band_r * x_zero_band_i + x_zero_band_i * x_zero_band_r; + + x_zero_band_r = temp_r * temp - temp_i * x_zero_band_i; + x_zero_band_i = temp_r * x_zero_band_i + temp_i * temp; + + for (k = 0; k < IXHEAACE_HBE_OPER_BLK_LEN_4; k++) { + temp = *ptr_norm++; + temp_i = *ptr_norm++; + + temp_r = temp * x_zero_band_r - temp_i * x_zero_band_i; + temp_i = temp * x_zero_band_i + temp_i * x_zero_band_r; + + *ptr_out++ += (temp_r * 0.6666667f); + *ptr_out++ += (temp_i * 0.6666667f); + + ptr_norm += 254; + ptr_out += 126; + } + + ptr_norm -= 128 * 11; + ptr_out -= 128 * 4; + ptr_x_norm += 126; + i++; + } + + ptr_out -= (128 * 2 * qmf_voc_columns) - 2; + } +} + +VOID ixheaace_hbe_post_anal_xprod2(ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer, + WORD32 qmf_voc_columns, WORD32 qmf_band_idx, FLOAT32 p, + FLOAT32 *ptr_cos_sin_theta) { + WORD32 i; + FLOAT32 *ptr_norm = &pstr_hbe_txposer->norm_qmf_in_buf[1][2 * qmf_band_idx]; + FLOAT32 *ptr_out = &pstr_hbe_txposer->qmf_out_buf[1][2 * qmf_band_idx]; + FLOAT32 *ptr_x_norm = + &pstr_hbe_txposer->norm_qmf_in_buf[IXHEAACE_HBE_ZERO_BAND_IDX][2 * qmf_band_idx]; + + ixheaace_norm_qmf_in_buf_2(pstr_hbe_txposer, qmf_band_idx); + + while (qmf_band_idx < pstr_hbe_txposer->x_over_qmf[1]) { + WORD32 n1, n2; + FLOAT64 temp_fac; + FLOAT32 mag_cmplx_gain = 1.666666667f; + temp_fac = (2.0 * qmf_band_idx + 1 - p) * 0.5; + n1 = ((WORD32)(temp_fac)) << 1; + n2 = ((WORD32)(temp_fac + p)) << 1; + + for (i = 0; i < qmf_voc_columns; i++) { + WORD32 k; + FLOAT32 x_zero_band_r, x_zero_band_i; + + x_zero_band_r = *ptr_x_norm++; + x_zero_band_i = *ptr_x_norm++; + + for (k = 1; k < (IXHEAACE_HBE_OPER_BLK_LEN_2 + 1); k++) { + register FLOAT32 tmp_r, tmp_i; + tmp_r = *ptr_norm++; + tmp_i = *ptr_norm++; + + *ptr_out++ += ((tmp_r * x_zero_band_r - tmp_i * x_zero_band_i) * 0.3333333f); + + *ptr_out++ += ((tmp_r * x_zero_band_i + tmp_i * x_zero_band_r) * 0.3333333f); + + ptr_norm += 126; + ptr_out += 126; + } + ptr_norm -= 128 * 9; + ptr_out -= 128 * 8; + ptr_x_norm += 126; + + { + WORD32 max_trans_fac, max_n1, max_n2; + FLOAT32 max_mag_value; + FLOAT32 mag_zero_band, mag_n1_band, mag_n2_band, temp; + + FLOAT32 *ptr_qmf_in_buf_ri = pstr_hbe_txposer->qmf_in_buf[i + IXHEAACE_HBE_ZERO_BAND_IDX]; + + mag_zero_band = + ptr_qmf_in_buf_ri[2 * qmf_band_idx] * ptr_qmf_in_buf_ri[2 * qmf_band_idx] + + ptr_qmf_in_buf_ri[2 * qmf_band_idx + 1] * ptr_qmf_in_buf_ri[2 * qmf_band_idx + 1]; + + mag_n1_band = ptr_qmf_in_buf_ri[n1] * ptr_qmf_in_buf_ri[n1] + + ptr_qmf_in_buf_ri[n1 + 1] * ptr_qmf_in_buf_ri[n1 + 1]; + mag_n2_band = ptr_qmf_in_buf_ri[n2] * ptr_qmf_in_buf_ri[n2] + + ptr_qmf_in_buf_ri[n2 + 1] * ptr_qmf_in_buf_ri[n2 + 1]; + + temp = min(mag_n1_band, mag_n2_band); + + max_mag_value = 0; + max_trans_fac = 0; + max_n1 = 0; + max_n2 = 0; + + if (temp > 0) { + max_mag_value = temp; + max_trans_fac = 1; + max_n1 = n1; + max_n2 = n2; + } + + if (max_mag_value > mag_zero_band && max_n1 >= 0 && + max_n2 < IXHEAACE_TWICE_QMF_SYNTH_CH_NUM - 1) { + FLOAT32 vec_y_r[2], vec_y_i[2]; + FLOAT32 temp_r, temp_i, tmp_r1; + WORD32 mid_trans_fac, idx; + FLOAT64 base; + FLOAT32 mag_scaling_fac = 0.0f; + + mid_trans_fac = 2 - max_trans_fac; + + x_zero_band_r = ptr_qmf_in_buf_ri[max_n1]; + x_zero_band_i = ptr_qmf_in_buf_ri[max_n1 + 1]; + base = 1e-17; + base = base + x_zero_band_r * x_zero_band_r; + base = base + x_zero_band_i * x_zero_band_i; + + mag_scaling_fac = (FLOAT32)(1.0f / base); + mag_scaling_fac = (FLOAT32)sqrt(sqrt(mag_scaling_fac)); + + x_zero_band_r *= mag_scaling_fac; + x_zero_band_i *= mag_scaling_fac; + + temp_r = x_zero_band_r; + temp_i = x_zero_band_i; + for (idx = 0; idx < mid_trans_fac - 1; idx++) { + FLOAT32 tmp = x_zero_band_r; + x_zero_band_r = x_zero_band_r * temp_r - x_zero_band_i * temp_i; + x_zero_band_i = tmp * temp_i + x_zero_band_i * temp_r; + } + + for (k = 0; k < 2; k++) { + temp_r = pstr_hbe_txposer->qmf_in_buf[i + IXHEAACE_HBE_ZERO_BAND_IDX - 1 + k][max_n2]; + + temp_i = + pstr_hbe_txposer->qmf_in_buf[i + IXHEAACE_HBE_ZERO_BAND_IDX - 1 + k][max_n2 + 1]; + + base = 1e-17; + base = base + temp_r * temp_r; + base = base + temp_i * temp_i; + + mag_scaling_fac = (FLOAT32)(1.0f / base); + mag_scaling_fac = (FLOAT32)sqrt(sqrt(mag_scaling_fac)); + + temp_r *= mag_scaling_fac; + temp_i *= mag_scaling_fac; + + vec_y_r[k] = temp_r; + vec_y_i[k] = temp_i; + } + + temp_r = vec_y_r[0] * x_zero_band_r - vec_y_i[0] * x_zero_band_i; + temp_i = vec_y_r[0] * x_zero_band_i + vec_y_i[0] * x_zero_band_r; + + tmp_r1 = (FLOAT32)(ptr_cos_sin_theta[0] * temp_r - ptr_cos_sin_theta[1] * temp_i); + temp_i = (FLOAT32)(ptr_cos_sin_theta[0] * temp_i + ptr_cos_sin_theta[1] * temp_r); + + pstr_hbe_txposer + ->qmf_out_buf[i * 2 + (IXHEAACE_HBE_ZERO_BAND_IDX - 1)][2 * qmf_band_idx] += + (FLOAT32)(mag_cmplx_gain * tmp_r1); + + pstr_hbe_txposer + ->qmf_out_buf[i * 2 + (IXHEAACE_HBE_ZERO_BAND_IDX - 1)][2 * qmf_band_idx + 1] += + (FLOAT32)(mag_cmplx_gain * temp_i); + + temp_r = vec_y_r[1] * x_zero_band_r - vec_y_i[1] * x_zero_band_i; + temp_i = vec_y_r[1] * x_zero_band_i + vec_y_i[1] * x_zero_band_r; + + pstr_hbe_txposer + ->qmf_out_buf[i * 2 + (1 + IXHEAACE_HBE_ZERO_BAND_IDX - 1)][2 * qmf_band_idx] += + (FLOAT32)(mag_cmplx_gain * temp_r); + + pstr_hbe_txposer + ->qmf_out_buf[i * 2 + (1 + IXHEAACE_HBE_ZERO_BAND_IDX - 1)][2 * qmf_band_idx + 1] += + (FLOAT32)(mag_cmplx_gain * temp_i); + } + } + } + + ptr_out -= (128 * 2 * qmf_voc_columns) - 2; + ptr_norm -= (128 * qmf_voc_columns) - 2; + ptr_x_norm -= (128 * qmf_voc_columns) - 2; + qmf_band_idx++; + } +} + +VOID ixheaace_hbe_post_anal_xprod3(ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer, + WORD32 qmf_voc_columns, WORD32 qmf_band_idx, FLOAT32 p, + WORD32 pitch_in_bins_idx) { + WORD32 i, inp_band_idx, rem; + + FLOAT32 *ptr_out_buf = &pstr_hbe_txposer->qmf_out_buf[2][2 * qmf_band_idx]; + + while (qmf_band_idx < pstr_hbe_txposer->x_over_qmf[2]) { + FLOAT32 temp_r, temp_i; + FLOAT32 temp_r1, temp_i1; + const FLOAT32 *ptr_sel, *ptr_sel1; + + inp_band_idx = (2 * qmf_band_idx) / 3; + ptr_sel = &ixheaac_sel_case[(inp_band_idx + 1) & 3][0]; + ptr_sel1 = &ixheaac_sel_case[((inp_band_idx + 1) & 3) + 1][0]; + rem = 2 * qmf_band_idx - 3 * inp_band_idx; + + if (rem == 0 || rem == 1) { + FLOAT32 *ptr_in_buf = &pstr_hbe_txposer->qmf_in_buf[0][2 * inp_band_idx]; + + for (i = 0; i < qmf_voc_columns; i += 1) { + WORD32 k; + FLOAT32 vec_x[2 * IXHEAACE_HBE_OPER_WIN_LEN]; + FLOAT32 *ptr_vec_x = &vec_x[0]; + FLOAT32 x_zero_band_r, x_zero_band_i; + + FLOAT32 mag_scaling_fac; + + for (k = 0; k < (IXHEAACE_HBE_OPER_BLK_LEN_3); k += 2) { + FLOAT64 base1; + FLOAT64 base = 1e-17; + + temp_r = ptr_in_buf[0]; + temp_i = ptr_in_buf[1]; + + ptr_in_buf += 256; + + base1 = base + temp_r * temp_r; + base1 = base1 + temp_i * temp_i; + + mag_scaling_fac = (FLOAT32)(ixheaace_cbrt_calc((FLOAT32)base1)); + + ptr_vec_x[0] = temp_r * mag_scaling_fac; + ptr_vec_x[1] = temp_i * mag_scaling_fac; + + temp_r = ptr_in_buf[0]; + temp_i = ptr_in_buf[1]; + + ptr_in_buf -= 128; + + temp_r1 = ptr_sel[0] * temp_r + ptr_sel[1] * temp_i; + temp_i1 = ptr_sel[2] * temp_r + ptr_sel[3] * temp_i; + + temp_r = ptr_in_buf[0]; + temp_i = ptr_in_buf[1]; + + temp_r1 += ptr_sel[4] * temp_r + ptr_sel[5] * temp_i; + temp_i1 += ptr_sel[6] * temp_r + ptr_sel[7] * temp_i; + + temp_r1 *= 0.3984033437f; + temp_i1 *= 0.3984033437f; + + base1 = base + temp_r1 * temp_r1; + base1 = base1 + temp_i1 * temp_i1; + mag_scaling_fac = (FLOAT32)(ixheaace_cbrt_calc((FLOAT32)base1)); + + ptr_vec_x[2] = temp_r1 * mag_scaling_fac; + ptr_vec_x[3] = temp_i1 * mag_scaling_fac; + + ptr_vec_x += 4; + ptr_in_buf += 256; + } + ptr_vec_x = &vec_x[0]; + temp_r = vec_x[2 * (IXHEAACE_HBE_ZERO_BAND_IDX - 2)]; + temp_i = vec_x[(2 * (IXHEAACE_HBE_ZERO_BAND_IDX - 2)) + 1]; + + x_zero_band_r = temp_r * temp_r - temp_i * temp_i; + x_zero_band_i = temp_r * temp_i + temp_i * temp_r; + + for (k = 0; k < (IXHEAACE_HBE_OPER_BLK_LEN_3); k++) { + temp_r = ptr_vec_x[0] * x_zero_band_r - ptr_vec_x[1] * x_zero_band_i; + temp_i = ptr_vec_x[0] * x_zero_band_i + ptr_vec_x[1] * x_zero_band_r; + + ptr_out_buf[0] += (temp_r * 0.4714045f); + ptr_out_buf[1] += (temp_i * 0.4714045f); + + ptr_vec_x += 2; + ptr_out_buf += 128; + } + + ixheaace_hbe_xprod_proc_3(pstr_hbe_txposer, qmf_band_idx, i, p, pitch_in_bins_idx); + + ptr_in_buf -= 128 * 11; + ptr_out_buf -= 128 * 6; + } + } else { + FLOAT32 *ptr_in_buf = &pstr_hbe_txposer->qmf_in_buf[0][2 * inp_band_idx]; + FLOAT32 *ptr_in_buf1 = &pstr_hbe_txposer->qmf_in_buf[0][2 * (inp_band_idx + 1)]; + + for (i = 0; i < qmf_voc_columns; i++) { + WORD32 k; + FLOAT32 vec_x[2 * IXHEAACE_HBE_OPER_WIN_LEN]; + FLOAT32 vec_x_cap[2 * IXHEAACE_HBE_OPER_WIN_LEN]; + + FLOAT32 x_zero_band_r, x_zero_band_i; + FLOAT32 *ptr_vec_x = &vec_x[0]; + FLOAT32 *ptr_vec_x_cap = &vec_x_cap[0]; + + FLOAT32 mag_scaling_fac; + + for (k = 0; k < (IXHEAACE_HBE_OPER_BLK_LEN_3); k += 2) { + FLOAT32 tmp_vr, tmp_vi; + FLOAT32 tmp_cr, tmp_ci; + FLOAT64 base1; + FLOAT64 base = 1e-17; + + temp_r1 = ptr_in_buf[0]; + temp_i1 = ptr_in_buf[1]; + temp_r = ptr_in_buf1[0]; + temp_i = ptr_in_buf1[1]; + + base1 = base + temp_r * temp_r; + base1 = base1 + temp_i * temp_i; + + mag_scaling_fac = (FLOAT32)(ixheaace_cbrt_calc((FLOAT32)base1)); + + ptr_vec_x[0] = temp_r * mag_scaling_fac; + ptr_vec_x[1] = temp_i * mag_scaling_fac; + + base1 = base + temp_r1 * temp_r1; + base1 = base1 + temp_i1 * temp_i1; + + mag_scaling_fac = (FLOAT32)(ixheaace_cbrt_calc((FLOAT32)base1)); + + ptr_vec_x_cap[0] = temp_r1 * mag_scaling_fac; + ptr_vec_x_cap[1] = temp_i1 * mag_scaling_fac; + + ptr_in_buf += 256; + + temp_r = ptr_in_buf[0]; + temp_i = ptr_in_buf[1]; + + temp_r1 = ptr_sel[0] * temp_r + ptr_sel[1] * temp_i; + temp_i1 = ptr_sel[2] * temp_r + ptr_sel[3] * temp_i; + + ptr_in_buf -= 128; + + temp_r = ptr_in_buf[0]; + temp_i = ptr_in_buf[1]; + + tmp_cr = temp_r1 + ptr_sel[4] * temp_r + ptr_sel[5] * temp_i; + tmp_ci = temp_i1 + ptr_sel[6] * temp_r + ptr_sel[7] * temp_i; + + ptr_in_buf1 += 256; + + temp_r = ptr_in_buf1[0]; + temp_i = ptr_in_buf1[1]; + + temp_r1 = ptr_sel1[0] * temp_r + ptr_sel1[1] * temp_i; + temp_i1 = ptr_sel1[2] * temp_r + ptr_sel1[3] * temp_i; + + ptr_in_buf1 -= 128; + + temp_r = ptr_in_buf1[0]; + temp_i = ptr_in_buf1[1]; + + tmp_vr = temp_r1 + ptr_sel1[4] * temp_r + ptr_sel1[5] * temp_i; + tmp_vi = temp_i1 + ptr_sel1[6] * temp_r + ptr_sel1[7] * temp_i; + + tmp_cr *= 0.3984033437f; + tmp_ci *= 0.3984033437f; + + tmp_vr *= 0.3984033437f; + tmp_vi *= 0.3984033437f; + + base1 = base + tmp_vr * tmp_vr; + base1 = base1 + tmp_vi * tmp_vi; + + mag_scaling_fac = (FLOAT32)(ixheaace_cbrt_calc((FLOAT32)base1)); + + ptr_vec_x[2] = tmp_vr * mag_scaling_fac; + ptr_vec_x[3] = tmp_vi * mag_scaling_fac; + + base1 = base + tmp_cr * tmp_cr; + base1 = base1 + tmp_ci * tmp_ci; + + mag_scaling_fac = (FLOAT32)(ixheaace_cbrt_calc((FLOAT32)base1)); + + ptr_vec_x_cap[2] = tmp_cr * mag_scaling_fac; + ptr_vec_x_cap[3] = tmp_ci * mag_scaling_fac; + + ptr_in_buf += 256; + ptr_in_buf1 += 256; + ptr_vec_x += 4; + ptr_vec_x_cap += 4; + } + ptr_vec_x = &vec_x[0]; + ptr_vec_x_cap = &vec_x_cap[0]; + + temp_r = vec_x_cap[2 * (IXHEAACE_HBE_ZERO_BAND_IDX - 2)]; + temp_i = vec_x_cap[2 * (IXHEAACE_HBE_ZERO_BAND_IDX - 2) + 1]; + temp_r1 = vec_x[2 * (IXHEAACE_HBE_ZERO_BAND_IDX - 2)]; + temp_i1 = vec_x[2 * (IXHEAACE_HBE_ZERO_BAND_IDX - 2) + 1]; + + x_zero_band_r = temp_r * temp_r - temp_i * temp_i; + x_zero_band_i = temp_r * temp_i + temp_i * temp_r; + + temp_r = temp_r1 * temp_r1 - temp_i1 * temp_i1; + temp_i = temp_r1 * temp_i1 + temp_i1 * temp_r1; + + for (k = 0; k < (IXHEAACE_HBE_OPER_BLK_LEN_3); k++) { + temp_r1 = ptr_vec_x[0] * x_zero_band_r - ptr_vec_x[1] * x_zero_band_i; + temp_i1 = ptr_vec_x[0] * x_zero_band_i + ptr_vec_x[1] * x_zero_band_r; + + temp_r1 += ptr_vec_x_cap[0] * temp_r - ptr_vec_x_cap[1] * temp_i; + temp_i1 += ptr_vec_x_cap[0] * temp_i + ptr_vec_x_cap[1] * temp_r; + + ptr_out_buf[0] += (temp_r1 * 0.23570225f); + ptr_out_buf[1] += (temp_i1 * 0.23570225f); + + ptr_out_buf += 128; + ptr_vec_x += 2; + ptr_vec_x_cap += 2; + } + + ixheaace_hbe_xprod_proc_3(pstr_hbe_txposer, qmf_band_idx, i, p, pitch_in_bins_idx); + + ptr_in_buf -= 128 * 11; + ptr_in_buf1 -= 128 * 11; + ptr_out_buf -= 128 * 6; + } + } + + ptr_out_buf -= (256 * qmf_voc_columns) - 2; + qmf_band_idx++; + } +} + +VOID ixheaace_hbe_post_anal_xprod4(ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer, + WORD32 qmf_voc_columns, WORD32 qmf_band_idx, FLOAT32 p, + WORD32 pitch_in_bins_idx) { + WORD32 i, inp_band_idx; + FLOAT32 *ptr_out = &pstr_hbe_txposer->qmf_out_buf[3][2 * qmf_band_idx]; + + ixheaace_norm_qmf_in_buf_4(pstr_hbe_txposer, ((qmf_band_idx >> 1) - 1)); + + while (qmf_band_idx < pstr_hbe_txposer->x_over_qmf[3]) { + WORD32 ip_idx; + FLOAT32 temp, temp_r, temp_i; + FLOAT32 *ptr_norm, *ptr_x_norm; + inp_band_idx = qmf_band_idx >> 1; + ip_idx = (qmf_band_idx & 1) ? (inp_band_idx + 1) : (inp_band_idx - 1); + + ptr_norm = &pstr_hbe_txposer->norm_qmf_in_buf[0][2 * ip_idx]; + ptr_x_norm = &pstr_hbe_txposer->norm_qmf_in_buf[IXHEAACE_HBE_ZERO_BAND_IDX][2 * inp_band_idx]; + + for (i = 0; i < qmf_voc_columns; i++) { + WORD32 k; + FLOAT32 x_zero_band_r, x_zero_band_i; + + temp_r = x_zero_band_r = *ptr_x_norm++; + temp_i = x_zero_band_i = *ptr_x_norm++; + + temp = x_zero_band_r * x_zero_band_r - x_zero_band_i * x_zero_band_i; + x_zero_band_i = x_zero_band_r * x_zero_band_i + x_zero_band_i * x_zero_band_r; + + x_zero_band_r = temp_r * temp - temp_i * x_zero_band_i; + x_zero_band_i = temp_r * x_zero_band_i + temp_i * temp; + + for (k = 0; k < IXHEAACE_HBE_OPER_BLK_LEN_4; k++) { + temp = *ptr_norm++; + temp_i = *ptr_norm++; + + temp_r = temp * x_zero_band_r - temp_i * x_zero_band_i; + temp_i = temp * x_zero_band_i + temp_i * x_zero_band_r; + + *ptr_out++ += (temp_r * 0.6666667f); + *ptr_out++ += (temp_i * 0.6666667f); + + ptr_norm += 254; + ptr_out += 126; + } + + ptr_norm -= 128 * 11; + ptr_out -= 128 * 4; + ptr_x_norm += 126; + + ixheaace_hbe_xprod_proc_4(pstr_hbe_txposer, qmf_band_idx, i, p, pitch_in_bins_idx); + } + + ptr_out -= (128 * 2 * qmf_voc_columns) - 2; + qmf_band_idx++; + } +} + +IA_ERRORCODE ixheaace_hbe_post_anal_process(ixheaace_str_esbr_hbe_txposer *pstr_hbe_txposer, + WORD32 pitch_in_bins, WORD32 sbr_upsamp_4_flg) { + FLOAT32 p; + WORD32 trans_fac; + WORD32 qmf_voc_columns = pstr_hbe_txposer->no_bins / 2; + FLOAT32 ptr_cos_sin_theta[2]; + + p = (sbr_upsamp_4_flg) ? (FLOAT32)(pitch_in_bins * 0.04166666666666) + : (FLOAT32)(pitch_in_bins * 0.08333333333333); + + if (p < IXHEAACE_SBR_CONST_PMIN) { + trans_fac = 2; + if (trans_fac <= pstr_hbe_txposer->max_stretch) { + ixheaace_hbe_post_anal_prod2(pstr_hbe_txposer, qmf_voc_columns, + pstr_hbe_txposer->x_over_qmf[0]); + } + + trans_fac = 3; + if (trans_fac <= pstr_hbe_txposer->max_stretch) { + ixheaace_hbe_post_anal_prod3(pstr_hbe_txposer, qmf_voc_columns, + pstr_hbe_txposer->x_over_qmf[1]); + } + + trans_fac = 4; + if (trans_fac <= pstr_hbe_txposer->max_stretch) { + if (pstr_hbe_txposer->x_over_qmf[2] <= 1) { + return IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_VALUE; + } + ixheaace_hbe_post_anal_prod4(pstr_hbe_txposer, qmf_voc_columns, + pstr_hbe_txposer->x_over_qmf[2]); + } + } else { + trans_fac = 2; + if (trans_fac <= pstr_hbe_txposer->max_stretch) { + ptr_cos_sin_theta[0] = + ixheaac_hbe_x_prod_cos_table_trans_2[((pitch_in_bins + sbr_upsamp_4_flg * 128) << 1) + + 0]; + ptr_cos_sin_theta[1] = + ixheaac_hbe_x_prod_cos_table_trans_2[((pitch_in_bins + sbr_upsamp_4_flg * 128) << 1) + + 1]; + + ixheaace_hbe_post_anal_xprod2(pstr_hbe_txposer, qmf_voc_columns, + pstr_hbe_txposer->x_over_qmf[0], p, ptr_cos_sin_theta); + } + + trans_fac = 3; + if (trans_fac <= pstr_hbe_txposer->max_stretch) { + ixheaace_hbe_post_anal_xprod3(pstr_hbe_txposer, qmf_voc_columns, + pstr_hbe_txposer->x_over_qmf[1], p, + (pitch_in_bins + sbr_upsamp_4_flg * 128)); + } + + trans_fac = 4; + if (trans_fac <= pstr_hbe_txposer->max_stretch) { + if (pstr_hbe_txposer->x_over_qmf[2] <= 1) { + return IA_EXHEAACE_EXE_NONFATAL_ESBR_INVALID_VALUE; + } + ixheaace_hbe_post_anal_xprod4(pstr_hbe_txposer, qmf_voc_columns, + pstr_hbe_txposer->x_over_qmf[2], p, + (pitch_in_bins + sbr_upsamp_4_flg * 128)); + } + } + return IA_NO_ERROR; +} VOID ixheaace_hbe_repl_spec(WORD32 x_over_qmf[IXHEAACE_MAX_NUM_PATCHES], FLOAT32 qmf_buf_real[][64], FLOAT32 qmf_buf_imag[][64], WORD32 no_bins, WORD32 max_stretch) { diff --git a/encoder/ixheaace_sbr_header.h b/encoder/ixheaace_sbr_header.h index a443bd3..c18b93b 100644 --- a/encoder/ixheaace_sbr_header.h +++ b/encoder/ixheaace_sbr_header.h @@ -42,6 +42,10 @@ typedef struct ixheaace_str_sbr_hdr_data { WORD32 freq_scale; WORD32 sbr_pre_proc; + WORD32 sbr_pvc_active; + WORD32 sbr_pvc_mode; + WORD32 sbr_harmonic; + WORD32 sbr_inter_tes_active; WORD32 hq_esbr; ixheaace_sr_mode sample_rate_mode; diff --git a/encoder/ixheaace_sbr_main.c b/encoder/ixheaace_sbr_main.c index 64a828b..cfcf5ce 100644 --- a/encoder/ixheaace_sbr_main.c +++ b/encoder/ixheaace_sbr_main.c @@ -22,6 +22,10 @@ #include "ixheaac_type_def.h" #include "ixheaac_constants.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" #include "ixheaace_api.h" #include "ixheaace_aac_constants.h" #include "ixheaace_error_codes.h" @@ -48,12 +52,15 @@ #include "ixheaace_rom.h" #include "ixheaace_common_rom.h" #include "ixheaace_bitbuffer.h" + #include "ixheaace_sbr_main.h" #include "ixheaace_common_rom.h" #include "ixheaace_sbr_missing_harmonics_det.h" #include "ixheaace_sbr_inv_filtering_estimation.h" #include "ixheaace_sbr_noise_floor_est.h" #include "ixheaace_sbr_ton_corr.h" +#include "iusace_esbr_pvc.h" +#include "iusace_esbr_inter_tes.h" #include "ixheaace_sbr.h" #include "ixheaace_sbr_freq_scaling.h" @@ -66,6 +73,26 @@ #include "ixheaace_sbr_crc.h" #include "ixheaace_sbr_enc_struct.h" +VOID ixheaace_set_usac_sbr_params(ixheaace_pstr_sbr_enc pstr_env_enc, WORD32 usac_indep_flag, + WORD32 sbr_pre_proc, WORD32 sbr_pvc_active, WORD32 sbr_pvc_mode, + WORD32 inter_tes_active, WORD32 sbr_harmonic, + WORD32 sbr_patching_mode) { + WORD32 ch; + pstr_env_enc->str_sbr_bs.usac_indep_flag = usac_indep_flag; + pstr_env_enc->str_sbr_hdr.sbr_pre_proc = sbr_pre_proc; + pstr_env_enc->str_sbr_hdr.sbr_pvc_active = sbr_pvc_active; + pstr_env_enc->str_sbr_hdr.sbr_pvc_mode = sbr_pvc_mode; + pstr_env_enc->str_sbr_hdr.sbr_inter_tes_active = inter_tes_active; + pstr_env_enc->str_sbr_hdr.sbr_harmonic = sbr_harmonic; + for (ch = 0; ch < pstr_env_enc->str_sbr_cfg.num_ch; ch++) { + pstr_env_enc->pstr_env_channel[ch]->enc_env_data.sbr_inter_tes = inter_tes_active; + pstr_env_enc->pstr_env_channel[ch]->enc_env_data.sbr_patching_mode = sbr_patching_mode; + } +} +FLOAT32 *ixheaace_get_hbe_resample_buffer(ixheaace_pstr_sbr_enc pstr_env_enc) { + return pstr_env_enc->ptr_hbe_resample_buf; +} + static FLAG ia_enhaacplus_enc_get_sbr_tuning_table_idx( UWORD32 bitrate, UWORD32 num_ch, UWORD32 sample_rate, ixheaace_str_qmf_tabs *pstr_qmf_tab, UWORD32 *ptr_closest_br, WORD32 *ptr_idx_sr, WORD32 *ptr_idx_ch, WORD32 *ptr_idx_entry, @@ -178,6 +205,11 @@ static IA_ERRORCODE ixheaace_create_env_channel( if (params->frame_flag_960 == 1) { pstr_env->str_sbr_qmf.num_time_slots = 15; } + if (pstr_sbr_cfg->sbr_codec == USAC_SBR) { + if (USAC_SBR_RATIO_INDEX_4_1 == pstr_sbr_cfg->sbr_ratio_idx) { + pstr_env->str_sbr_qmf.rate = 4; + } + } } ixheaace_create_qmf_bank(&pstr_env->str_sbr_qmf, pstr_sbr_tab, params->is_ld_sbr); @@ -217,10 +249,12 @@ static IA_ERRORCODE ixheaace_create_env_channel( } tran_fc = (tran_fc * 4 * 64 / pstr_sbr_cfg->sample_freq + 1) >> 1; - + if (params->sbr_codec == USAC_SBR) { + pstr_env->str_sbr_extract_env.sbr_ratio_idx = params->sbr_ratio_idx; + } err_code = ixheaace_create_extract_sbr_envelope( ch, &pstr_env->str_sbr_extract_env, start_index, ptr_common_buffer2, ptr_sbr_env_r_buf, - ptr_sbr_env_i_buf, params->frame_flag_480, params->sbr_codec); + ptr_sbr_env_i_buf, params->is_ld_sbr, params->frame_flag_480, params->sbr_codec); if (err_code) { return err_code; } @@ -248,14 +282,88 @@ static IA_ERRORCODE ixheaace_create_env_channel( &pstr_env->str_sbr_trans_detector, pstr_sbr_cfg->sample_freq, params->codec_settings.standard_bitrate * params->codec_settings.num_channels, params->codec_settings.bit_rate, params->tran_thr, params->tran_det_mode, tran_fc, - params->frame_flag_480, params->is_ld_sbr, pstr_sbr_cfg->ptr_freq_band_tab[0][0]); + params->frame_flag_480, params->is_ld_sbr, params->sbr_ratio_idx, params->sbr_codec, + pstr_sbr_cfg->ptr_freq_band_tab[0][0]); pstr_sbr_cfg->xpos_control_switch = params->sbr_xpos_ctrl; pstr_env->enc_env_data.no_harmonics = pstr_sbr_cfg->num_scf[HI]; pstr_env->enc_env_data.synthetic_coding = pstr_sbr_cfg->detect_missing_harmonics; pstr_env->enc_env_data.add_harmonic_flag = 0; + ixheaace_init_esbr_inter_tes(&pstr_env->str_inter_tes_enc, params->sbr_ratio_idx); + pstr_env->enc_env_data.ptr_sbr_inter_tes_shape = pstr_env->str_inter_tes_enc.bs_tes_shape; + pstr_env->enc_env_data.ptr_sbr_inter_tes_shape_mode = + pstr_env->str_inter_tes_enc.bs_tes_shape_mode; - { pstr_env->enc_env_data.harmonic_sbr = 0; } + if (params->sbr_codec == USAC_SBR) { + pstr_env->enc_env_data.harmonic_sbr = pstr_sbr_hdr->sbr_harmonic; + if (1 == pstr_env->enc_env_data.harmonic_sbr) { + WORD32 persist_mem_used = 0, bd; + WORD32 upsamp_4_flag, num_aac_samples, num_out_samples; + switch (pstr_sbr_cfg->sbr_ratio_idx) { + case USAC_SBR_RATIO_INDEX_2_1: + upsamp_4_flag = 0; + num_aac_samples = 1024; + num_out_samples = 2048; + break; + case USAC_SBR_RATIO_INDEX_4_1: + upsamp_4_flag = 1; + num_aac_samples = 1024; + num_out_samples = 4096; + break; + case USAC_SBR_RATIO_INDEX_8_3: + upsamp_4_flag = 0; + num_aac_samples = 768; + num_out_samples = 2048; + break; + default: + upsamp_4_flag = 0; + num_aac_samples = 1024; + num_out_samples = 2048; + break; + } + + ixheaace_esbr_hbe_data_init( + pstr_env->pstr_hbe_enc->pstr_hbe_txposer, num_aac_samples, upsamp_4_flag, + num_out_samples, pstr_env->pstr_hbe_enc->ptr_hbe_txposer_buffers, &persist_mem_used); + + ixheaace_esbr_qmf_init(&(pstr_env->pstr_hbe_enc->str_codec_qmf_bank), + pstr_sbr_cfg->sbr_ratio_idx, num_out_samples); + + for (bd = 0; bd < (IXHEAACE_MAX_FREQ_COEFFS / 2 + 1); bd++) { + pstr_env->pstr_hbe_enc->pstr_hbe_txposer->freq_band_tbl_lo[bd] = + pstr_sbr_cfg->sbr_freq_band_tab_lo[bd]; + pstr_env->pstr_hbe_enc->pstr_hbe_txposer->freq_band_tbl_hi[bd] = + pstr_sbr_cfg->sbr_freq_band_tab_hi[bd]; + } + + for (; bd < (IXHEAACE_MAX_FREQ_COEFFS + 1); bd++) { + pstr_env->pstr_hbe_enc->pstr_hbe_txposer->freq_band_tbl_hi[bd] = + pstr_sbr_cfg->sbr_freq_band_tab_hi[bd]; + } + + pstr_env->pstr_hbe_enc->pstr_hbe_txposer->ptr_freq_band_tab[LO] = + pstr_env->pstr_hbe_enc->pstr_hbe_txposer->freq_band_tbl_lo; + pstr_env->pstr_hbe_enc->pstr_hbe_txposer->ptr_freq_band_tab[HI] = + pstr_env->pstr_hbe_enc->pstr_hbe_txposer->freq_band_tbl_hi; + pstr_env->pstr_hbe_enc->pstr_hbe_txposer->num_sf_bands[0] = + (WORD16)pstr_sbr_cfg->num_scf[0]; + pstr_env->pstr_hbe_enc->pstr_hbe_txposer->num_sf_bands[1] = + (WORD16)pstr_sbr_cfg->num_scf[1]; + pstr_env->pstr_hbe_enc->pstr_hbe_txposer->upsamp_4_flag = upsamp_4_flag; + err_code = ixheaace_dft_hbe_data_reinit(pstr_env->pstr_hbe_enc->pstr_hbe_txposer); + if (err_code) { + return err_code; + } + err_code = ixheaace_qmf_hbe_data_reinit(pstr_env->pstr_hbe_enc->pstr_hbe_txposer); + if (err_code) { + return err_code; + } + } + } else + + { + pstr_env->enc_env_data.harmonic_sbr = 0; + } return err_code; } @@ -454,6 +562,9 @@ VOID ixheaace_initialize_sbr_defaults(ixheaace_pstr_sbr_cfg pstr_config) { pstr_config->frame_flag_960 = 0; pstr_config->frame_flag_480 = 0; pstr_config->hq_esbr = 0; + pstr_config->sbr_pvc_active = 0; + pstr_config->sbr_harmonic = 0; + pstr_config->sbr_ratio_idx = 0; // NO_SBR } static IA_ERRORCODE ia_enhaacplus_enc_update_freq_band_tab( @@ -462,10 +573,14 @@ static IA_ERRORCODE ia_enhaacplus_enc_update_freq_band_tab( IA_ERRORCODE err_code = IA_NO_ERROR; WORD32 k0, k2; WORD32 samp_freq = pstr_sbr_cfg->sample_freq; - + if ((pstr_sbr_cfg->sbr_codec == USAC_SBR) && + (pstr_sbr_cfg->sbr_ratio_idx == USAC_SBR_RATIO_INDEX_4_1)) { + samp_freq = samp_freq / 2; + } err_code = ixheaace_find_start_and_stop_band( samp_freq, num_qmf_ch, pstr_sbr_hdr->sbr_start_freq, pstr_sbr_hdr->sbr_stop_freq, - pstr_sbr_hdr->sample_rate_mode, &k0, &k2); + pstr_sbr_hdr->sample_rate_mode, &k0, &k2, pstr_sbr_cfg->sbr_ratio_idx, + pstr_sbr_cfg->sbr_codec); if (err_code) { return err_code; } @@ -510,7 +625,7 @@ ixheaace_env_encode_frame(ixheaace_pstr_sbr_enc pstr_env_encoder, FLOAT32 *ptr_s UWORD8 *ptr_num_anc_bytes, UWORD8 *ptr_anc_data, ixheaace_str_sbr_tabs *pstr_sbr_tab, ixheaace_comm_tables *pstr_common_tab, UWORD8 *ptr_mps_data, - WORD32 mps_bits, WORD32 flag_fl_small) { + WORD32 mps_bits, WORD32 flag_fl_small, WORD32 *usac_stat_bits) { IA_ERRORCODE err_code = IA_NO_ERROR; if (pstr_env_encoder != NULL) { @@ -582,11 +697,14 @@ ixheaace_env_encode_frame(ixheaace_pstr_sbr_enc pstr_env_encoder, FLOAT32 *ptr_s } if (ptr_anc_data) { - *ptr_num_anc_bytes = pstr_env_encoder->sbr_payload_size; + *ptr_num_anc_bytes = (UWORD8)pstr_env_encoder->sbr_payload_size; memcpy(ptr_anc_data, pstr_env_encoder->sbr_payload, pstr_env_encoder->sbr_payload_size); } + if (usac_stat_bits) { + *usac_stat_bits = pstr_env_encoder->str_cmon_data.sbr_hdr_bits + + pstr_env_encoder->str_cmon_data.sbr_data_bits; + } } - return err_code; } @@ -619,11 +737,18 @@ VOID ixheaace_sbr_set_scratch_ptr(ixheaace_pstr_sbr_enc pstr_env_enc, VOID *ptr_ pstr_env_enc->ptr_sbr_enc_scr = ptr_scr; } -WORD32 ixheaace_sbr_enc_pers_size(WORD32 num_ch, WORD32 use_ps) { +WORD32 ixheaace_sbr_enc_pers_size(WORD32 num_ch, WORD32 use_ps, WORD32 harmonic_sbr) { WORD32 num_bytes; num_bytes = sizeof(struct ixheaace_str_sbr_enc); num_bytes += sizeof(struct ixheaace_str_enc_channel) * num_ch; + num_bytes += sizeof(ixheaace_pvc_enc); num_bytes += 2 * sizeof(FLOAT32) * num_ch * QMF_FILTER_LENGTH; + if (1 == harmonic_sbr) { + num_bytes += sizeof(ixheaace_str_hbe_enc) * num_ch; + num_bytes += sizeof(ixheaace_str_esbr_hbe_txposer) * num_ch; + num_bytes += IXHEAACE_MAX_HBE_PERSISTENT_SIZE * num_ch; + num_bytes += ESBR_RESAMP_SAMPLES * sizeof(FLOAT32); + } num_bytes += sizeof(FLOAT32) * num_ch * 5 * NO_OF_ESTIMATES * MAXIMUM_FREQ_COEFFS; num_bytes += sizeof(FLOAT32) * num_ch * MAX_QMF_TIME_SLOTS * IXHEAACE_QMF_CHANNELS; @@ -643,7 +768,8 @@ WORD32 ixheaace_sbr_enc_pers_size(WORD32 num_ch, WORD32 use_ps) { return num_bytes; } -VOID ia_enhaacplus_enc_sbr_set_persist_buf(WORD8 *ptr_base, WORD32 num_ch, WORD32 use_ps) { +VOID ia_enhaacplus_enc_sbr_set_persist_buf(WORD8 *ptr_base, WORD32 num_ch, WORD32 use_ps, + WORD32 harmonic_sbr) { struct ixheaace_str_sbr_enc *pstr_env_enc; WORD8 *ptr_curr_mem = (WORD8 *)((WORD8 *)ptr_base + sizeof(struct ixheaace_str_sbr_enc)); WORD32 i; @@ -679,7 +805,25 @@ VOID ia_enhaacplus_enc_sbr_set_persist_buf(WORD8 *ptr_base, WORD32 num_ch, WORD3 ptr_curr_mem += 2 * sizeof(pstr_env_enc->ptr_common_buffer2[0]) * IXHEAACE_QMF_TIME_SLOTS * IXHEAACE_QMF_CHANNELS; } - + // PVC encoder + pstr_env_enc->pstr_pvc_enc = (ixheaace_pvc_enc *)ptr_curr_mem; + ptr_curr_mem = ptr_curr_mem + sizeof(ixheaace_pvc_enc); + // Harmonic SBR + if (1 == harmonic_sbr) { + for (i = 0; i < num_ch; i++) { + pstr_env_enc->pstr_env_channel[i]->pstr_hbe_enc = (ixheaace_str_hbe_enc *)ptr_curr_mem; + ptr_curr_mem = ptr_curr_mem + sizeof(ixheaace_str_hbe_enc); + pstr_env_enc->pstr_env_channel[i]->pstr_hbe_enc->pstr_hbe_txposer = + (ixheaace_str_esbr_hbe_txposer *)ptr_curr_mem; + ptr_curr_mem = ptr_curr_mem + sizeof(ixheaace_str_esbr_hbe_txposer); + pstr_env_enc->pstr_env_channel[i]->pstr_hbe_enc->ptr_hbe_txposer_buffers = + (VOID *)ptr_curr_mem; + ptr_curr_mem = ptr_curr_mem + IXHEAACE_MAX_HBE_PERSISTENT_SIZE; + } + pstr_env_enc->ptr_hbe_resample_buf = (FLOAT32 *)ptr_curr_mem; + ptr_curr_mem = + ptr_curr_mem + (ESBR_RESAMP_SAMPLES * sizeof(pstr_env_enc->ptr_hbe_resample_buf[0])); + } if (use_ps) { pstr_env_enc->pstr_env_channel[1] = (struct ixheaace_str_enc_channel *)(ptr_curr_mem); ptr_curr_mem = ptr_curr_mem + sizeof(struct ixheaace_str_enc_channel); @@ -722,7 +866,8 @@ ixheaace_env_open(ixheaace_pstr_sbr_enc *pstr_env_encoder, ixheaace_pstr_sbr_cfg ixheaace_sbr_set_scratch_ptr(pstr_env_enc, ptr_sbr_scratch); ia_enhaacplus_enc_sbr_set_persist_buf((WORD8 *)pstr_env_enc, - params->codec_settings.num_channels, params->use_ps); + params->codec_settings.num_channels, params->use_ps, + params->sbr_harmonic); if ((params->codec_settings.num_channels < 1) || (params->codec_settings.num_channels > IXHEAACE_MAX_CH_IN_BS_ELE)) { @@ -769,13 +914,23 @@ ixheaace_env_open(ixheaace_pstr_sbr_enc *pstr_env_encoder, ixheaace_pstr_sbr_cfg pstr_env_enc->str_sbr_cfg.is_ld_sbr = params->is_ld_sbr; pstr_env_enc->str_sbr_cfg.sbr_codec = params->sbr_codec; pstr_env_enc->str_sbr_cfg.is_esbr = params->is_esbr; - + if (pstr_env_enc->str_sbr_cfg.sbr_codec == USAC_SBR) { + pstr_env_enc->str_sbr_cfg.sbr_ratio_idx = params->sbr_ratio_idx; + } pstr_env_enc->str_sbr_cfg.stereo_mode = (params->codec_settings.num_channels == 2) ? params->stereo_mode : IXHEAACE_SBR_MODE_MONO; if (params->codec_settings.sample_freq <= 24000) { pstr_env_enc->str_sbr_hdr.sample_rate_mode = IXHEAACE_DUAL_RATE; - { pstr_env_enc->str_sbr_cfg.sample_freq = 2 * params->codec_settings.sample_freq; } + if (params->sbr_codec == USAC_SBR) { + pstr_env_enc->str_sbr_cfg.sample_freq = 2 * params->codec_settings.sample_freq; + if (USAC_SBR_RATIO_INDEX_4_1 == params->sbr_ratio_idx) { + pstr_env_enc->str_sbr_cfg.sample_freq = 4 * params->codec_settings.sample_freq; + pstr_env_enc->str_sbr_hdr.sample_rate_mode = IXHEAACE_QUAD_RATE; + } + } else { + pstr_env_enc->str_sbr_cfg.sample_freq = 2 * params->codec_settings.sample_freq; + } } else { pstr_env_enc->str_sbr_hdr.sample_rate_mode = IXHEAACE_SINGLE_RATE; pstr_env_enc->str_sbr_cfg.sample_freq = params->codec_settings.sample_freq; @@ -786,8 +941,9 @@ ixheaace_env_open(ixheaace_pstr_sbr_enc *pstr_env_encoder, ixheaace_pstr_sbr_cfg pstr_env_enc->str_sbr_bs.count_send_header_data = 0; } if (params->send_header_data_time > 0) { - pstr_env_enc->str_sbr_bs.nr_send_header_data = (WORD32)( - params->send_header_data_time * 0.001 * pstr_env_enc->str_sbr_cfg.sample_freq / 2048); + pstr_env_enc->str_sbr_bs.nr_send_header_data = + (WORD32)(params->send_header_data_time * 0.001 * pstr_env_enc->str_sbr_cfg.sample_freq / + 2048); pstr_env_enc->str_sbr_bs.nr_send_header_data = ixheaac_max32(pstr_env_enc->str_sbr_bs.nr_send_header_data, 1); @@ -833,6 +989,8 @@ ixheaace_env_open(ixheaace_pstr_sbr_enc *pstr_env_encoder, ixheaace_pstr_sbr_cfg (params->sbr_smoothing_length != SBR_SMOOTHING_LENGTH_DEFAULT)) { pstr_env_enc->str_sbr_hdr.header_extra_2 = 1; } + pstr_env_enc->str_sbr_hdr.sbr_harmonic = params->sbr_harmonic; + pstr_env_enc->str_sbr_hdr.sbr_pvc_active = params->sbr_pvc_active; pstr_env_enc->str_sbr_hdr.hq_esbr = params->hq_esbr; pstr_env_enc->str_sbr_cfg.detect_missing_harmonics = params->detect_missing_harmonics; @@ -885,7 +1043,9 @@ ixheaace_env_open(ixheaace_pstr_sbr_enc *pstr_env_encoder, ixheaace_pstr_sbr_cfg } pstr_env_enc->str_cmon_data.sbr_num_channels = pstr_env_enc->str_sbr_cfg.num_ch; - + if (USAC_SBR == params->sbr_codec) { + ixheaace_pvc_enc_init(pstr_env_enc->pstr_pvc_enc, params->sbr_pvc_rate); + } *pstr_env_encoder = pstr_env_enc; *ptr_core_bw = pstr_env_enc->str_sbr_cfg.xover_freq; diff --git a/encoder/ixheaace_sbr_main.h b/encoder/ixheaace_sbr_main.h index cbb1dd9..e53b972 100644 --- a/encoder/ixheaace_sbr_main.h +++ b/encoder/ixheaace_sbr_main.h @@ -78,6 +78,10 @@ typedef struct ixheaace_str_sbr_cfg { WORD32 frame_flag_960; WORD32 is_ld_sbr; WORD32 is_esbr; + WORD32 sbr_pvc_rate; + WORD32 sbr_ratio_idx; + WORD32 sbr_pvc_active; + WORD32 sbr_harmonic; WORD32 hq_esbr; ixheaace_sbr_codec_type sbr_codec; } ixheaace_str_sbr_cfg, *ixheaace_pstr_sbr_cfg; @@ -107,9 +111,6 @@ ixheaace_env_open(ixheaace_pstr_sbr_enc *pstr_env_encoder, ixheaace_pstr_sbr_cfg VOID ixheaace_env_close(ixheaace_pstr_sbr_enc pstr_env_encoder); -WORD32 -ixheaace_sbr_get_x_over_freq(ixheaace_pstr_sbr_enc ptr_env, WORD32 xoverFreq); - WORD32 ixheaace_sbr_get_stop_freq_raw(ixheaace_pstr_sbr_enc ptr_env); @@ -118,12 +119,19 @@ ixheaace_env_encode_frame(ixheaace_pstr_sbr_enc ptr_env_encoder, FLOAT32 *sample FLOAT32 *core_buffer, UWORD32 time_sn_stride, UWORD8 *num_anc_bytes, UWORD8 *anc_data, ixheaace_str_sbr_tabs *pstr_sbr_tab, ixheaace_comm_tables *common_tab, UWORD8 *mps_data, WORD32 mps_bits, - WORD32 flag_framelength_small); + WORD32 flag_framelength_small, WORD32 *usac_stat_bits); VOID ixheaace_sbr_set_scratch_ptr(ixheaace_pstr_sbr_enc h_env_enc, VOID *scr); -WORD32 ixheaace_sbr_enc_pers_size(WORD32 num_chan, WORD32 use_ps); +WORD32 ixheaace_sbr_enc_pers_size(WORD32 num_chan, WORD32 use_ps, WORD32 harmonic_sbr); WORD32 ixheaace_sbr_enc_scr_size(VOID); +VOID ixheaace_set_usac_sbr_params(ixheaace_pstr_sbr_enc h_env_enc, WORD32 usac_indep_flag, + WORD32 sbr_pre_proc, WORD32 sbr_pvc_active, WORD32 sbr_pvc_mode, + WORD32 inter_tes_active, WORD32 sbr_harmonic, + WORD32 sbr_patching_mode); + +FLOAT32 *ixheaace_get_hbe_resample_buffer(ixheaace_pstr_sbr_enc h_env_enc); + IA_ERRORCODE ixheaace_extract_sbr_envelope(FLOAT32 *ptr_in_time, FLOAT32 *ptr_core_buf, UWORD32 time_sn_stride, ixheaace_pstr_sbr_enc pstr_env_enc, diff --git a/encoder/ixheaace_sbr_missing_harmonics_det.c b/encoder/ixheaace_sbr_missing_harmonics_det.c index 0fcacb9..5171650 100644 --- a/encoder/ixheaace_sbr_missing_harmonics_det.c +++ b/encoder/ixheaace_sbr_missing_harmonics_det.c @@ -47,6 +47,8 @@ #include "ixheaace_sbr_noise_floor_est.h" #include "ixheaace_sbr_ton_corr.h" +#include "iusace_esbr_pvc.h" +#include "iusace_esbr_inter_tes.h" #include "ixheaace_sbr.h" static VOID ia_enhaacplus_enc_diff(FLOAT32 *ptr_tonal_orig, FLOAT32 *ptr_diff_map_2_scfb, diff --git a/encoder/ixheaace_sbr_noise_floor_est.c b/encoder/ixheaace_sbr_noise_floor_est.c index 1224961..6131a6d 100644 --- a/encoder/ixheaace_sbr_noise_floor_est.c +++ b/encoder/ixheaace_sbr_noise_floor_est.c @@ -48,6 +48,8 @@ #include "ixheaace_sbr_noise_floor_est.h" #include "ixheaace_sbr_ton_corr.h" +#include "iusace_esbr_pvc.h" +#include "iusace_esbr_inter_tes.h" #include "ixheaace_sbr.h" #include "ixheaace_common_utils.h" @@ -306,8 +308,10 @@ ixheaace_reset_sbr_noise_floor_estimate(ixheaace_pstr_noise_flr_est_sbr pstr_noi if (pstr_noise_floor_est_sbr->noise_groups == 0) { pstr_noise_floor_est_sbr->num_of_noise_bands = 1; } else { - pstr_noise_floor_est_sbr->num_of_noise_bands = (WORD32)( - (pstr_noise_floor_est_sbr->noise_groups * log((FLOAT32)k2 / kx) * SBR_INV_LOG_2) + 0.5f); + pstr_noise_floor_est_sbr->num_of_noise_bands = + (WORD32)((pstr_noise_floor_est_sbr->noise_groups * log((FLOAT32)k2 / kx) * + SBR_INV_LOG_2) + + 0.5f); if (pstr_noise_floor_est_sbr->num_of_noise_bands == 0) { pstr_noise_floor_est_sbr->num_of_noise_bands = 1; diff --git a/encoder/ixheaace_sbr_qmf_enc.c b/encoder/ixheaace_sbr_qmf_enc.c index f6b2237..71a79fd 100644 --- a/encoder/ixheaace_sbr_qmf_enc.c +++ b/encoder/ixheaace_sbr_qmf_enc.c @@ -941,9 +941,14 @@ VOID ixheaace_sbr_analysis_filtering(const FLOAT32 *ptr_time_in, WORD32 time_sn_ } } -VOID ixheaace_get_energy_from_cplx_qmf(FLOAT32 **ptr_energy_vals, FLOAT32 **ptr_real_values, - FLOAT32 **ptr_imag_values, WORD32 is_ld_sbr, - WORD32 num_time_slots, WORD32 samp_ratio_fac) { +VOID ixheaace_get_energy_from_cplx_qmf( + FLOAT32 **ptr_energy_vals, FLOAT32 **ptr_real_values, FLOAT32 **ptr_imag_values, + WORD32 is_ld_sbr, WORD32 num_time_slots, WORD32 samp_ratio_fac, + FLOAT32 qmf_buf_real[IXHEAACE_TIMESLOT_BUFFER_SIZE + 2 * 32][IXHEAACE_NUM_QMF_SYNTH_CHANNELS], + FLOAT32 qmf_buf_imag[IXHEAACE_TIMESLOT_BUFFER_SIZE + 2 * 32][IXHEAACE_NUM_QMF_SYNTH_CHANNELS], + WORD32 op_delay, WORD32 harmonic_sbr) + +{ WORD32 j, k; FLOAT32 avg_fac = 0.5f; if (samp_ratio_fac == 4) { @@ -953,11 +958,21 @@ VOID ixheaace_get_energy_from_cplx_qmf(FLOAT32 **ptr_energy_vals, FLOAT32 **ptr_ FLOAT32 *ptr_energy_val = &ptr_energy_vals[0][0]; FLOAT32 *ptr_real = &ptr_real_values[0][0]; FLOAT32 *ptr_imag = &ptr_imag_values[0][0]; + FLOAT32 *ptr_hbe_real = &qmf_buf_real[op_delay][0]; + FLOAT32 *ptr_hbe_imag = &qmf_buf_imag[op_delay][0]; k = (num_time_slots - 1); while (k >= 0) { for (j = 63; j >= 0; j--) { FLOAT32 tmp = 0.0f; - { + if (harmonic_sbr == 1) { + FLOAT32 real_hbe, imag_hbe; + real_hbe = *(ptr_hbe_real); + imag_hbe = *(ptr_hbe_imag); + tmp += (real_hbe * real_hbe) + (imag_hbe * imag_hbe); + *ptr_energy_val = tmp; + ptr_hbe_real++; + ptr_hbe_imag++; + } else { FLOAT32 real, imag; WORD32 i; for (i = 0; i < samp_ratio_fac; i++) { @@ -971,7 +986,10 @@ VOID ixheaace_get_energy_from_cplx_qmf(FLOAT32 **ptr_energy_vals, FLOAT32 **ptr_ } ptr_energy_val++; } - { + if (harmonic_sbr == 1) { + ptr_hbe_real += 64; + ptr_hbe_imag += 64; + } else { ptr_real += 64; ptr_imag += 64; } diff --git a/encoder/ixheaace_sbr_qmf_enc.h b/encoder/ixheaace_sbr_qmf_enc.h index bcfce7f..024c342 100644 --- a/encoder/ixheaace_sbr_qmf_enc.h +++ b/encoder/ixheaace_sbr_qmf_enc.h @@ -67,9 +67,12 @@ VOID ixheaace_sbr_analysis_filtering(const FLOAT32 *ptr_time_in, WORD32 time_sn_ VOID ixheaace_create_qmf_bank(ixheaace_pstr_sbr_qmf_filter_bank pstr_sbr_qmf_handle, ixheaace_str_sbr_tabs *pstr_sbr_tab, WORD32 is_ld_sbr); -VOID ixheaace_get_energy_from_cplx_qmf(FLOAT32 **ptr_energy_vals, FLOAT32 **ptr_real_values, - FLOAT32 **ptr_imag_values, WORD32 is_ld_sbr, - WORD32 num_time_slots, WORD32 samp_ratio_fac); +VOID ixheaace_get_energy_from_cplx_qmf( + FLOAT32 **ptr_energy_vals, FLOAT32 **ptr_real_values, FLOAT32 **ptr_imag_values, + WORD32 is_ld_sbr, WORD32 num_time_slots, WORD32 samp_ratio_fac, + FLOAT32 qmf_buf_real[IXHEAACE_TIMESLOT_BUFFER_SIZE + 2 * 32][IXHEAACE_NUM_QMF_SYNTH_CHANNELS], + FLOAT32 qmf_buf_imag[IXHEAACE_TIMESLOT_BUFFER_SIZE + 2 * 32][IXHEAACE_NUM_QMF_SYNTH_CHANNELS], + WORD32 op_delay, WORD32 harmonic_sbr); VOID ixheaace_enc_synthesis_qmf_filtering(FLOAT32 **ptr_sbr_re, FLOAT32 **ptr_sbr_im, FLOAT32 *time_float, diff --git a/encoder/ixheaace_sbr_rom.c b/encoder/ixheaace_sbr_rom.c index 7ab6a91..311119f 100644 --- a/encoder/ixheaace_sbr_rom.c +++ b/encoder/ixheaace_sbr_rom.c @@ -1203,6 +1203,454 @@ const WORD32 ixheaace_stop_freq_44k[14] = {23, 25, 27, 29, 32, 34, 37, const WORD32 ixheaace_stop_freq_48k[14] = {21, 23, 25, 27, 30, 32, 35, 38, 42, 45, 49, 54, 59, 64}; +const ixheaace_str_qmf_dec_tabs_struct ixheaace_str_aac_qmf_tabs = { + // w_16[2 * 12] = + {0, 32767, 0, 32767, 0, 32767, 12540, 30274, 23170, 23170, 30274, 12540, + 23170, 23170, 32767, 0, 23170, -23170, 30274, 12540, 23170, -23170, -12540, -30274}, + + // dig_rev_tab_4_16[2]= + {0, 16}, + + // FLOAT32 esbr_qmf_c[1280]; + {0.0000000000f, -0.0002762643f, -0.0002808846f, -0.0002473758f, -0.0002437613f, + -0.0002446894f, -0.0002520357f, -0.0002613282f, -0.0002733283f, -0.0002838899f, + -0.0002935464f, -0.0003066373f, -0.0003156245f, -0.0003270165f, -0.0003388845f, + -0.0003470806f, -0.0003578868f, -0.0003627520f, -0.0003720471f, -0.0003745297f, + -0.0003840686f, -0.0003862423f, -0.0003917166f, -0.0003889934f, -0.0003901832f, + -0.0003900724f, -0.0003878986f, -0.0003815396f, -0.0003765000f, -0.0003659676f, + -0.0003607695f, -0.0003458967f, -0.0003325206f, -0.0003170797f, -0.0002973059f, + -0.0002782287f, -0.0002572786f, -0.0002303161f, -0.0002047559f, -0.0001750586f, + -0.0001448488f, -0.0001049167f, -0.0000723188f, -0.0000308666f, 0.0000067474f, + 0.0000547189f, 0.0001021507f, 0.0001474763f, 0.0002013268f, 0.0002553693f, + 0.0003119686f, 0.0003729011f, 0.0004304221f, 0.0004942992f, 0.0005625077f, + 0.0006288942f, 0.0006951247f, 0.0007721609f, 0.0008434041f, 0.0009174130f, + 0.0009920569f, 0.0010730790f, 0.0011508625f, 0.0012312806f, 0.0013100877f, + 0.0013935231f, 0.0014734722f, 0.0015562710f, 0.0016369806f, 0.0017209435f, + 0.0018004132f, 0.0018801959f, 0.0019603714f, 0.0020409876f, 0.0021132133f, + 0.0021865359f, 0.0022604924f, 0.0023303230f, 0.0023966280f, 0.0024568802f, + 0.0025196511f, 0.0025703677f, 0.0026230582f, 0.0026735840f, 0.0027098388f, + 0.0027438018f, 0.0027737855f, 0.0027969009f, 0.0028110321f, 0.0028227598f, + 0.0028194599f, 0.0028133057f, 0.0027958562f, 0.0027702181f, 0.0027376891f, + 0.0026919488f, 0.0026357877f, 0.0025691136f, 0.0024919843f, 0.0024054733f, + 0.0023019763f, 0.0021900930f, 0.0020625819f, 0.0019228202f, 0.0017700621f, + 0.0016045941f, 0.0014223377f, 0.0012254268f, 0.0010137088f, 0.0007892339f, + 0.0005451164f, 0.0002916132f, 0.0000138022f, -0.0002732140f, -0.0005784067f, + -0.0009019736f, -0.0012413361f, -0.0015966888f, -0.0019700560f, -0.0023611297f, + -0.0027668604f, -0.0031896145f, -0.0036307906f, -0.0040899115f, -0.0045662662f, + -0.0050575109f, -0.0055657774f, -0.0060924999f, 0.0066359108f, 0.0071952334f, + 0.0077702776f, 0.0083662355f, 0.0089716688f, 0.0095936209f, 0.0102265896f, + 0.0108733773f, 0.0115340082f, 0.0122080492f, 0.0128937922f, 0.0135929715f, + 0.0143036088f, 0.0150251333f, 0.0157508813f, 0.0164877046f, 0.0172310472f, + 0.0179848783f, 0.0187406428f, 0.0195026845f, 0.0202674586f, 0.0210324544f, + 0.0218048766f, 0.0225744210f, 0.0233421512f, 0.0241082851f, 0.0248692874f, + 0.0256278068f, 0.0263815373f, 0.0271226391f, 0.0278586820f, 0.0285808221f, + 0.0292957835f, 0.0299918745f, 0.0306727588f, 0.0313428901f, 0.0319857933f, + 0.0326123536f, 0.0332183763f, 0.0338037983f, 0.0343521908f, 0.0348815136f, + 0.0353814363f, 0.0358501337f, 0.0362841301f, 0.0366810113f, 0.0370501801f, + 0.0373726264f, 0.0376568660f, 0.0379004180f, 0.0380996242f, 0.0382496081f, + 0.0383546725f, 0.0384087004f, 0.0384115018f, 0.0383602455f, 0.0382525362f, + 0.0380874164f, 0.0378652886f, 0.0375788137f, 0.0372332186f, 0.0368202999f, + 0.0363387316f, 0.0357913189f, 0.0351766534f, 0.0344832018f, 0.0337262526f, + 0.0328845344f, 0.0319722407f, 0.0309801381f, 0.0299083292f, 0.0287576355f, + 0.0275230017f, 0.0262046903f, 0.0247989334f, 0.0233151652f, 0.0217384398f, + 0.0200729147f, 0.0183209050f, 0.0164791960f, 0.0145412004f, 0.0125153782f, + 0.0103998538f, 0.0081850626f, 0.0058811912f, 0.0034818430f, 0.0009882799f, + -0.0016043447f, -0.0042855870f, -0.0070644412f, -0.0099417064f, -0.0129113644f, + -0.0159765631f, -0.0191388279f, -0.0223903414f, -0.0257402081f, -0.0291852653f, + -0.0327204913f, -0.0363471657f, -0.0400686450f, -0.0438773781f, -0.0477766693f, + -0.0517664775f, -0.0558413453f, -0.0600038990f, -0.0642501414f, -0.0685775876f, + -0.0729883239f, -0.0774803534f, -0.0820479393f, -0.0866904110f, -0.0914086252f, + -0.0961983353f, -0.1010625064f, -0.1059867889f, -0.1109826341f, -0.1160345450f, + -0.1211508438f, -0.1263240129f, -0.1315526664f, -0.1368317008f, -0.1421607137f, + -0.1475358307f, -0.1529549360f, -0.1584139466f, -0.1639056802f, -0.1694361269f, + -0.1749957055f, 0.1805794984f, 0.1861897707f, 0.1918175071f, 0.1974605918f, + 0.2031158805f, 0.2087848485f, 0.2144559920f, 0.2201276869f, 0.2257998288f, + 0.2314653993f, 0.2371226549f, 0.2427626550f, 0.2483854145f, 0.2539908886f, + 0.2595617473f, 0.2651120424f, 0.2706276774f, 0.2761025727f, 0.2815394700f, + 0.2869262099f, 0.2922701538f, 0.2975561619f, 0.3027891815f, 0.3079555035f, + 0.3130621314f, 0.3180989921f, 0.3230634928f, 0.3279508054f, 0.3327569962f, + 0.3374831676f, 0.3421176672f, 0.3466641307f, 0.3511194289f, 0.3554705083f, + 0.3597231209f, 0.3638724387f, 0.3679105937f, 0.3718414009f, 0.3756568730f, + 0.3793540299f, 0.3829337358f, 0.3863890469f, 0.3897143900f, 0.3929176629f, + 0.3959867954f, 0.3989233077f, 0.4017242789f, 0.4043847620f, 0.4069095552f, + 0.4092887938f, 0.4115209877f, 0.4136137664f, 0.4155519307f, 0.4173468649f, + 0.4189858735f, 0.4204770625f, 0.4218119085f, 0.4229909182f, 0.4240157902f, + 0.4248902500f, 0.4255985618f, 0.4261523485f, 0.4265510440f, 0.4267860353f, + 0.4268692732f, 0.4267860353f, 0.4265510440f, 0.4261523485f, 0.4255985618f, + 0.4248902500f, 0.4240157902f, 0.4229909182f, 0.4218119085f, 0.4204770625f, + 0.4189858735f, 0.4173468649f, 0.4155519307f, 0.4136137664f, 0.4115209877f, + 0.4092887938f, 0.4069095552f, 0.4043847620f, 0.4017242789f, 0.3989233077f, + 0.3959867954f, 0.3929176629f, 0.3897143900f, 0.3863890469f, 0.3829337358f, + 0.3793540299f, 0.3756568730f, 0.3718414009f, 0.3679105937f, 0.3638724387f, + 0.3597231209f, 0.3554705083f, 0.3511194289f, 0.3466641307f, 0.3421176672f, + 0.3374831676f, 0.3327569962f, 0.3279508054f, 0.3230634928f, 0.3180989921f, + 0.3130621314f, 0.3079555035f, 0.3027891815f, 0.2975561619f, 0.2922701538f, + 0.2869262099f, 0.2815394700f, 0.2761025727f, 0.2706276774f, 0.2651120424f, + 0.2595617473f, 0.2539908886f, 0.2483854145f, 0.2427626550f, 0.2371226549f, + 0.2314653993f, 0.2257998288f, 0.2201276869f, 0.2144559920f, 0.2087848485f, + 0.2031158805f, 0.1974605918f, 0.1918175071f, 0.1861897707f, -0.1805794984f, + -0.1749957055f, -0.1694361269f, -0.1639056802f, -0.1584139466f, -0.1529549360f, + -0.1475358307f, -0.1421607137f, -0.1368317008f, -0.1315526664f, -0.1263240129f, + -0.1211508438f, -0.1160345450f, -0.1109826341f, -0.1059867889f, -0.1010625064f, + -0.0961983353f, -0.0914086252f, -0.0866904110f, -0.0820479393f, -0.0774803534f, + -0.0729883239f, -0.0685775876f, -0.0642501414f, -0.0600038990f, -0.0558413453f, + -0.0517664775f, -0.0477766693f, -0.0438773781f, -0.0400686450f, -0.0363471657f, + -0.0327204913f, -0.0291852653f, -0.0257402081f, -0.0223903414f, -0.0191388279f, + -0.0159765631f, -0.0129113644f, -0.0099417064f, -0.0070644412f, -0.0042855870f, + -0.0016043447f, 0.0009882799f, 0.0034818430f, 0.0058811912f, 0.0081850626f, + 0.0103998538f, 0.0125153782f, 0.0145412004f, 0.0164791960f, 0.0183209050f, + 0.0200729147f, 0.0217384398f, 0.0233151652f, 0.0247989334f, 0.0262046903f, + 0.0275230017f, 0.0287576355f, 0.0299083292f, 0.0309801381f, 0.0319722407f, + 0.0328845344f, 0.0337262526f, 0.0344832018f, 0.0351766534f, 0.0357913189f, + 0.0363387316f, 0.0368202999f, 0.0372332186f, 0.0375788137f, 0.0378652886f, + 0.0380874164f, 0.0382525362f, 0.0383602455f, 0.0384115018f, 0.0384087004f, + 0.0383546725f, 0.0382496081f, 0.0380996242f, 0.0379004180f, 0.0376568660f, + 0.0373726264f, 0.0370501801f, 0.0366810113f, 0.0362841301f, 0.0358501337f, + 0.0353814363f, 0.0348815136f, 0.0343521908f, 0.0338037983f, 0.0332183763f, + 0.0326123536f, 0.0319857933f, 0.0313428901f, 0.0306727588f, 0.0299918745f, + 0.0292957835f, 0.0285808221f, 0.0278586820f, 0.0271226391f, 0.0263815373f, + 0.0256278068f, 0.0248692874f, 0.0241082851f, 0.0233421512f, 0.0225744210f, + 0.0218048766f, 0.0210324544f, 0.0202674586f, 0.0195026845f, 0.0187406428f, + 0.0179848783f, 0.0172310472f, 0.0164877046f, 0.0157508813f, 0.0150251333f, + 0.0143036088f, 0.0135929715f, 0.0128937922f, 0.0122080492f, 0.0115340082f, + 0.0108733773f, 0.0102265896f, 0.0095936209f, 0.0089716688f, 0.0083662355f, + 0.0077702776f, 0.0071952334f, -0.0066359108f, -0.0060924999f, -0.0055657774f, + -0.0050575109f, -0.0045662662f, -0.0040899115f, -0.0036307906f, -0.0031896145f, + -0.0027668604f, -0.0023611297f, -0.0019700560f, -0.0015966888f, -0.0012413361f, + -0.0009019736f, -0.0005784067f, -0.0002732140f, 0.0000138022f, 0.0002916132f, + 0.0005451164f, 0.0007892339f, 0.0010137088f, 0.0012254268f, 0.0014223377f, + 0.0016045941f, 0.0017700621f, 0.0019228202f, 0.0020625819f, 0.0021900930f, + 0.0023019763f, 0.0024054733f, 0.0024919843f, 0.0025691136f, 0.0026357877f, + 0.0026919488f, 0.0027376891f, 0.0027702181f, 0.0027958562f, 0.0028133057f, + 0.0028194599f, 0.0028227598f, 0.0028110321f, 0.0027969009f, 0.0027737855f, + 0.0027438018f, 0.0027098388f, 0.0026735840f, 0.0026230582f, 0.0025703677f, + 0.0025196511f, 0.0024568802f, 0.0023966280f, 0.0023303230f, 0.0022604924f, + 0.0021865359f, 0.0021132133f, 0.0020409876f, 0.0019603714f, 0.0018801959f, + 0.0018004132f, 0.0017209435f, 0.0016369806f, 0.0015562710f, 0.0014734722f, + 0.0013935231f, 0.0013100877f, 0.0012312806f, 0.0011508625f, 0.0010730790f, + 0.0009920569f, 0.0009174130f, 0.0008434041f, 0.0007721609f, 0.0006951247f, + 0.0006288942f, 0.0005625077f, 0.0004942992f, 0.0004304221f, 0.0003729011f, + 0.0003119686f, 0.0002553693f, 0.0002013268f, 0.0001474763f, 0.0001021507f, + 0.0000547189f, 0.0000067474f, -0.0000308666f, -0.0000723188f, -0.0001049167f, + -0.0001448488f, -0.0001750586f, -0.0002047559f, -0.0002303161f, -0.0002572786f, + -0.0002782287f, -0.0002973059f, -0.0003170797f, -0.0003325206f, -0.0003458967f, + -0.0003607695f, -0.0003659676f, -0.0003765000f, -0.0003815396f, -0.0003878986f, + -0.0003900724f, -0.0003901832f, -0.0003889934f, -0.0003917166f, -0.0003862423f, + -0.0003840686f, -0.0003745297f, -0.0003720471f, -0.0003627520f, -0.0003578868f, + -0.0003470806f, -0.0003388845f, -0.0003270165f, -0.0003156245f, -0.0003066373f, + -0.0002935464f, -0.0002838899f, -0.0002733283f, -0.0002613282f, -0.0002520357f, + -0.0002446894f, -0.0002437613f, -0.0002473758f, -0.0002808846f, -0.0002762643f, + 0.0000000000f, -0.0002762643f, -0.0002808846f, -0.0002473758f, -0.0002437613f, + -0.0002446894f, -0.0002520357f, -0.0002613282f, -0.0002733283f, -0.0002838899f, + -0.0002935464f, -0.0003066373f, -0.0003156245f, -0.0003270165f, -0.0003388845f, + -0.0003470806f, -0.0003578868f, -0.0003627520f, -0.0003720471f, -0.0003745297f, + -0.0003840686f, -0.0003862423f, -0.0003917166f, -0.0003889934f, -0.0003901832f, + -0.0003900724f, -0.0003878986f, -0.0003815396f, -0.0003765000f, -0.0003659676f, + -0.0003607695f, -0.0003458967f, -0.0003325206f, -0.0003170797f, -0.0002973059f, + -0.0002782287f, -0.0002572786f, -0.0002303161f, -0.0002047559f, -0.0001750586f, + -0.0001448488f, -0.0001049167f, -0.0000723188f, -0.0000308666f, 0.0000067474f, + 0.0000547189f, 0.0001021507f, 0.0001474763f, 0.0002013268f, 0.0002553693f, + 0.0003119686f, 0.0003729011f, 0.0004304221f, 0.0004942992f, 0.0005625077f, + 0.0006288942f, 0.0006951247f, 0.0007721609f, 0.0008434041f, 0.0009174130f, + 0.0009920569f, 0.0010730790f, 0.0011508625f, 0.0012312806f, 0.0013100877f, + 0.0013935231f, 0.0014734722f, 0.0015562710f, 0.0016369806f, 0.0017209435f, + 0.0018004132f, 0.0018801959f, 0.0019603714f, 0.0020409876f, 0.0021132133f, + 0.0021865359f, 0.0022604924f, 0.0023303230f, 0.0023966280f, 0.0024568802f, + 0.0025196511f, 0.0025703677f, 0.0026230582f, 0.0026735840f, 0.0027098388f, + 0.0027438018f, 0.0027737855f, 0.0027969009f, 0.0028110321f, 0.0028227598f, + 0.0028194599f, 0.0028133057f, 0.0027958562f, 0.0027702181f, 0.0027376891f, + 0.0026919488f, 0.0026357877f, 0.0025691136f, 0.0024919843f, 0.0024054733f, + 0.0023019763f, 0.0021900930f, 0.0020625819f, 0.0019228202f, 0.0017700621f, + 0.0016045941f, 0.0014223377f, 0.0012254268f, 0.0010137088f, 0.0007892339f, + 0.0005451164f, 0.0002916132f, 0.0000138022f, -0.0002732140f, -0.0005784067f, + -0.0009019736f, -0.0012413361f, -0.0015966888f, -0.0019700560f, -0.0023611297f, + -0.0027668604f, -0.0031896145f, -0.0036307906f, -0.0040899115f, -0.0045662662f, + -0.0050575109f, -0.0055657774f, -0.0060924999f, 0.0066359108f, 0.0071952334f, + 0.0077702776f, 0.0083662355f, 0.0089716688f, 0.0095936209f, 0.0102265896f, + 0.0108733773f, 0.0115340082f, 0.0122080492f, 0.0128937922f, 0.0135929715f, + 0.0143036088f, 0.0150251333f, 0.0157508813f, 0.0164877046f, 0.0172310472f, + 0.0179848783f, 0.0187406428f, 0.0195026845f, 0.0202674586f, 0.0210324544f, + 0.0218048766f, 0.0225744210f, 0.0233421512f, 0.0241082851f, 0.0248692874f, + 0.0256278068f, 0.0263815373f, 0.0271226391f, 0.0278586820f, 0.0285808221f, + 0.0292957835f, 0.0299918745f, 0.0306727588f, 0.0313428901f, 0.0319857933f, + 0.0326123536f, 0.0332183763f, 0.0338037983f, 0.0343521908f, 0.0348815136f, + 0.0353814363f, 0.0358501337f, 0.0362841301f, 0.0366810113f, 0.0370501801f, + 0.0373726264f, 0.0376568660f, 0.0379004180f, 0.0380996242f, 0.0382496081f, + 0.0383546725f, 0.0384087004f, 0.0384115018f, 0.0383602455f, 0.0382525362f, + 0.0380874164f, 0.0378652886f, 0.0375788137f, 0.0372332186f, 0.0368202999f, + 0.0363387316f, 0.0357913189f, 0.0351766534f, 0.0344832018f, 0.0337262526f, + 0.0328845344f, 0.0319722407f, 0.0309801381f, 0.0299083292f, 0.0287576355f, + 0.0275230017f, 0.0262046903f, 0.0247989334f, 0.0233151652f, 0.0217384398f, + 0.0200729147f, 0.0183209050f, 0.0164791960f, 0.0145412004f, 0.0125153782f, + 0.0103998538f, 0.0081850626f, 0.0058811912f, 0.0034818430f, 0.0009882799f, + -0.0016043447f, -0.0042855870f, -0.0070644412f, -0.0099417064f, -0.0129113644f, + -0.0159765631f, -0.0191388279f, -0.0223903414f, -0.0257402081f, -0.0291852653f, + -0.0327204913f, -0.0363471657f, -0.0400686450f, -0.0438773781f, -0.0477766693f, + -0.0517664775f, -0.0558413453f, -0.0600038990f, -0.0642501414f, -0.0685775876f, + -0.0729883239f, -0.0774803534f, -0.0820479393f, -0.0866904110f, -0.0914086252f, + -0.0961983353f, -0.1010625064f, -0.1059867889f, -0.1109826341f, -0.1160345450f, + -0.1211508438f, -0.1263240129f, -0.1315526664f, -0.1368317008f, -0.1421607137f, + -0.1475358307f, -0.1529549360f, -0.1584139466f, -0.1639056802f, -0.1694361269f, + -0.1749957055f, 0.1805794984f, 0.1861897707f, 0.1918175071f, 0.1974605918f, + 0.2031158805f, 0.2087848485f, 0.2144559920f, 0.2201276869f, 0.2257998288f, + 0.2314653993f, 0.2371226549f, 0.2427626550f, 0.2483854145f, 0.2539908886f, + 0.2595617473f, 0.2651120424f, 0.2706276774f, 0.2761025727f, 0.2815394700f, + 0.2869262099f, 0.2922701538f, 0.2975561619f, 0.3027891815f, 0.3079555035f, + 0.3130621314f, 0.3180989921f, 0.3230634928f, 0.3279508054f, 0.3327569962f, + 0.3374831676f, 0.3421176672f, 0.3466641307f, 0.3511194289f, 0.3554705083f, + 0.3597231209f, 0.3638724387f, 0.3679105937f, 0.3718414009f, 0.3756568730f, + 0.3793540299f, 0.3829337358f, 0.3863890469f, 0.3897143900f, 0.3929176629f, + 0.3959867954f, 0.3989233077f, 0.4017242789f, 0.4043847620f, 0.4069095552f, + 0.4092887938f, 0.4115209877f, 0.4136137664f, 0.4155519307f, 0.4173468649f, + 0.4189858735f, 0.4204770625f, 0.4218119085f, 0.4229909182f, 0.4240157902f, + 0.4248902500f, 0.4255985618f, 0.4261523485f, 0.4265510440f, 0.4267860353f, + 0.4268692732f, 0.4267860353f, 0.4265510440f, 0.4261523485f, 0.4255985618f, + 0.4248902500f, 0.4240157902f, 0.4229909182f, 0.4218119085f, 0.4204770625f, + 0.4189858735f, 0.4173468649f, 0.4155519307f, 0.4136137664f, 0.4115209877f, + 0.4092887938f, 0.4069095552f, 0.4043847620f, 0.4017242789f, 0.3989233077f, + 0.3959867954f, 0.3929176629f, 0.3897143900f, 0.3863890469f, 0.3829337358f, + 0.3793540299f, 0.3756568730f, 0.3718414009f, 0.3679105937f, 0.3638724387f, + 0.3597231209f, 0.3554705083f, 0.3511194289f, 0.3466641307f, 0.3421176672f, + 0.3374831676f, 0.3327569962f, 0.3279508054f, 0.3230634928f, 0.3180989921f, + 0.3130621314f, 0.3079555035f, 0.3027891815f, 0.2975561619f, 0.2922701538f, + 0.2869262099f, 0.2815394700f, 0.2761025727f, 0.2706276774f, 0.2651120424f, + 0.2595617473f, 0.2539908886f, 0.2483854145f, 0.2427626550f, 0.2371226549f, + 0.2314653993f, 0.2257998288f, 0.2201276869f, 0.2144559920f, 0.2087848485f, + 0.2031158805f, 0.1974605918f, 0.1918175071f, 0.1861897707f, -0.1805794984f, + -0.1749957055f, -0.1694361269f, -0.1639056802f, -0.1584139466f, -0.1529549360f, + -0.1475358307f, -0.1421607137f, -0.1368317008f, -0.1315526664f, -0.1263240129f, + -0.1211508438f, -0.1160345450f, -0.1109826341f, -0.1059867889f, -0.1010625064f, + -0.0961983353f, -0.0914086252f, -0.0866904110f, -0.0820479393f, -0.0774803534f, + -0.0729883239f, -0.0685775876f, -0.0642501414f, -0.0600038990f, -0.0558413453f, + -0.0517664775f, -0.0477766693f, -0.0438773781f, -0.0400686450f, -0.0363471657f, + -0.0327204913f, -0.0291852653f, -0.0257402081f, -0.0223903414f, -0.0191388279f, + -0.0159765631f, -0.0129113644f, -0.0099417064f, -0.0070644412f, -0.0042855870f, + -0.0016043447f, 0.0009882799f, 0.0034818430f, 0.0058811912f, 0.0081850626f, + 0.0103998538f, 0.0125153782f, 0.0145412004f, 0.0164791960f, 0.0183209050f, + 0.0200729147f, 0.0217384398f, 0.0233151652f, 0.0247989334f, 0.0262046903f, + 0.0275230017f, 0.0287576355f, 0.0299083292f, 0.0309801381f, 0.0319722407f, + 0.0328845344f, 0.0337262526f, 0.0344832018f, 0.0351766534f, 0.0357913189f, + 0.0363387316f, 0.0368202999f, 0.0372332186f, 0.0375788137f, 0.0378652886f, + 0.0380874164f, 0.0382525362f, 0.0383602455f, 0.0384115018f, 0.0384087004f, + 0.0383546725f, 0.0382496081f, 0.0380996242f, 0.0379004180f, 0.0376568660f, + 0.0373726264f, 0.0370501801f, 0.0366810113f, 0.0362841301f, 0.0358501337f, + 0.0353814363f, 0.0348815136f, 0.0343521908f, 0.0338037983f, 0.0332183763f, + 0.0326123536f, 0.0319857933f, 0.0313428901f, 0.0306727588f, 0.0299918745f, + 0.0292957835f, 0.0285808221f, 0.0278586820f, 0.0271226391f, 0.0263815373f, + 0.0256278068f, 0.0248692874f, 0.0241082851f, 0.0233421512f, 0.0225744210f, + 0.0218048766f, 0.0210324544f, 0.0202674586f, 0.0195026845f, 0.0187406428f, + 0.0179848783f, 0.0172310472f, 0.0164877046f, 0.0157508813f, 0.0150251333f, + 0.0143036088f, 0.0135929715f, 0.0128937922f, 0.0122080492f, 0.0115340082f, + 0.0108733773f, 0.0102265896f, 0.0095936209f, 0.0089716688f, 0.0083662355f, + 0.0077702776f, 0.0071952334f, -0.0066359108f, -0.0060924999f, -0.0055657774f, + -0.0050575109f, -0.0045662662f, -0.0040899115f, -0.0036307906f, -0.0031896145f, + -0.0027668604f, -0.0023611297f, -0.0019700560f, -0.0015966888f, -0.0012413361f, + -0.0009019736f, -0.0005784067f, -0.0002732140f, 0.0000138022f, 0.0002916132f, + 0.0005451164f, 0.0007892339f, 0.0010137088f, 0.0012254268f, 0.0014223377f, + 0.0016045941f, 0.0017700621f, 0.0019228202f, 0.0020625819f, 0.0021900930f, + 0.0023019763f, 0.0024054733f, 0.0024919843f, 0.0025691136f, 0.0026357877f, + 0.0026919488f, 0.0027376891f, 0.0027702181f, 0.0027958562f, 0.0028133057f, + 0.0028194599f, 0.0028227598f, 0.0028110321f, 0.0027969009f, 0.0027737855f, + 0.0027438018f, 0.0027098388f, 0.0026735840f, 0.0026230582f, 0.0025703677f, + 0.0025196511f, 0.0024568802f, 0.0023966280f, 0.0023303230f, 0.0022604924f, + 0.0021865359f, 0.0021132133f, 0.0020409876f, 0.0019603714f, 0.0018801959f, + 0.0018004132f, 0.0017209435f, 0.0016369806f, 0.0015562710f, 0.0014734722f, + 0.0013935231f, 0.0013100877f, 0.0012312806f, 0.0011508625f, 0.0010730790f, + 0.0009920569f, 0.0009174130f, 0.0008434041f, 0.0007721609f, 0.0006951247f, + 0.0006288942f, 0.0005625077f, 0.0004942992f, 0.0004304221f, 0.0003729011f, + 0.0003119686f, 0.0002553693f, 0.0002013268f, 0.0001474763f, 0.0001021507f, + 0.0000547189f, 0.0000067474f, -0.0000308666f, -0.0000723188f, -0.0001049167f, + -0.0001448488f, -0.0001750586f, -0.0002047559f, -0.0002303161f, -0.0002572786f, + -0.0002782287f, -0.0002973059f, -0.0003170797f, -0.0003325206f, -0.0003458967f, + -0.0003607695f, -0.0003659676f, -0.0003765000f, -0.0003815396f, -0.0003878986f, + -0.0003900724f, -0.0003901832f, -0.0003889934f, -0.0003917166f, -0.0003862423f, + -0.0003840686f, -0.0003745297f, -0.0003720471f, -0.0003627520f, -0.0003578868f, + -0.0003470806f, -0.0003388845f, -0.0003270165f, -0.0003156245f, -0.0003066373f, + -0.0002935464f, -0.0002838899f, -0.0002733283f, -0.0002613282f, -0.0002520357f, + -0.0002446894f, -0.0002437613f, -0.0002473758f, -0.0002808846f, -0.0002762643f}, + {0.0000000000f, -0.0002585454f, -0.0002471381f, -0.0002733283f, -0.0003022735f, + -0.0003309725f, -0.0003578868f, -0.0003737023f, -0.0003880670f, -0.0003901832f, + -0.0003836593f, -0.0003642349f, -0.0003325206f, -0.0002845877f, -0.0002217961f, + -0.0001448488f, -0.0000446842f, 0.0000705295f, 0.0002013268f, 0.0003525903f, + 0.0005170354f, 0.0006951247f, 0.0008927435f, 0.0010990070f, 0.0013100877f, + 0.0015286715f, 0.0017474336f, 0.0019603714f, 0.0021620949f, 0.0023524247f, + 0.0025196511f, 0.0026567420f, 0.0027537965f, 0.0028110321f, 0.0028153569f, + 0.0027593751f, 0.0026357877f, 0.0024343103f, 0.0021475893f, 0.0017700621f, + 0.0012910638f, 0.0007078615f, 0.0000138022f, -0.0007941178f, -0.0017211447f, + -0.0027668604f, -0.0039368710f, -0.0052269329f, 0.0066359108f, 0.0081675826f, + 0.0098046111f, 0.0115340082f, 0.0133599117f, 0.0152670480f, 0.0172310472f, + 0.0192486700f, 0.0212899297f, 0.0233421512f, 0.0253749676f, 0.0273679867f, + 0.0292957835f, 0.0311195124f, 0.0328143612f, 0.0343521908f, 0.0356939025f, + 0.0368040688f, 0.0376568660f, 0.0381996147f, 0.0384096317f, 0.0382525362f, + 0.0376743041f, 0.0366597772f, 0.0351766534f, 0.0331651047f, 0.0306228697f, + 0.0275230017f, 0.0238097552f, 0.0194889121f, 0.0145412004f, 0.0089233266f, + 0.0026506553f, -0.0042855870f, -0.0119214784f, -0.0202226657f, -0.0291852653f, + -0.0388281532f, -0.0491066054f, -0.0600038990f, -0.0715180784f, -0.0835954323f, + -0.0961983353f, -0.1093173549f, -0.1228752360f, -0.1368317008f, -0.1511485577f, + -0.1657491624f, 0.1805794984f, 0.1955795586f, 0.2106752247f, 0.2257998288f, + 0.2408826500f, 0.2558478415f, 0.2706276774f, 0.2851306200f, 0.2993004918f, + 0.3130621314f, 0.3263216913f, 0.3390280008f, 0.3511194289f, 0.3624893427f, + 0.3731132150f, 0.3829337358f, 0.3918499053f, 0.3998569846f, 0.4069095552f, + 0.4129161835f, 0.4178932011f, 0.4218119085f, 0.4245987833f, 0.4262852371f, + 0.4268692732f, 0.4262852371f, 0.4245987833f, 0.4218119085f, 0.4178932011f, + 0.4129161835f, 0.4069095552f, 0.3998569846f, 0.3918499053f, 0.3829337358f, + 0.3731132150f, 0.3624893427f, 0.3511194289f, 0.3390280008f, 0.3263216913f, + 0.3130621314f, 0.2993004918f, 0.2851306200f, 0.2706276774f, 0.2558478415f, + 0.2408826500f, 0.2257998288f, 0.2106752247f, 0.1955795586f, -0.1805794984f, + -0.1657491624f, -0.1511485577f, -0.1368317008f, -0.1228752360f, -0.1093173549f, + -0.0961983353f, -0.0835954323f, -0.0715180784f, -0.0600038990f, -0.0491066054f, + -0.0388281532f, -0.0291852653f, -0.0202226657f, -0.0119214784f, -0.0042855870f, + 0.0026506553f, 0.0089233266f, 0.0145412004f, 0.0194889121f, 0.0238097552f, + 0.0275230017f, 0.0306228697f, 0.0331651047f, 0.0351766534f, 0.0366597772f, + 0.0376743041f, 0.0382525362f, 0.0384096317f, 0.0381996147f, 0.0376568660f, + 0.0368040688f, 0.0356939025f, 0.0343521908f, 0.0328143612f, 0.0311195124f, + 0.0292957835f, 0.0273679867f, 0.0253749676f, 0.0233421512f, 0.0212899297f, + 0.0192486700f, 0.0172310472f, 0.0152670480f, 0.0133599117f, 0.0115340082f, + 0.0098046111f, 0.0081675826f, -0.0066359108f, -0.0052269329f, -0.0039368710f, + -0.0027668604f, -0.0017211447f, -0.0007941178f, 0.0000138022f, 0.0007078615f, + 0.0012910638f, 0.0017700621f, 0.0021475893f, 0.0024343103f, 0.0026357877f, + 0.0027593751f, 0.0028153569f, 0.0028110321f, 0.0027537965f, 0.0026567420f, + 0.0025196511f, 0.0023524247f, 0.0021620949f, 0.0019603714f, 0.0017474336f, + 0.0015286715f, 0.0013100877f, 0.0010990070f, 0.0008927435f, 0.0006951247f, + 0.0005170354f, 0.0003525903f, 0.0002013268f, 0.0000705295f, -0.0000446842f, + -0.0001448488f, -0.0002217961f, -0.0002845877f, -0.0003325206f, -0.0003642349f, + -0.0003836593f, -0.0003901832f, -0.0003880670f, -0.0003737023f, -0.0003578868f, + -0.0003309725f, -0.0003022735f, -0.0002733283f, -0.0002471381f, -0.0002585454f, + 0.0000000000f, -0.0002585454f, -0.0002471381f, -0.0002733283f, -0.0003022735f, + -0.0003309725f, -0.0003578868f, -0.0003737023f, -0.0003880670f, -0.0003901832f, + -0.0003836593f, -0.0003642349f, -0.0003325206f, -0.0002845877f, -0.0002217961f, + -0.0001448488f, -0.0000446842f, 0.0000705295f, 0.0002013268f, 0.0003525903f, + 0.0005170354f, 0.0006951247f, 0.0008927435f, 0.0010990070f, 0.0013100877f, + 0.0015286715f, 0.0017474336f, 0.0019603714f, 0.0021620949f, 0.0023524247f, + 0.0025196511f, 0.0026567420f, 0.0027537965f, 0.0028110321f, 0.0028153569f, + 0.0027593751f, 0.0026357877f, 0.0024343103f, 0.0021475893f, 0.0017700621f, + 0.0012910638f, 0.0007078615f, 0.0000138022f, -0.0007941178f, -0.0017211447f, + -0.0027668604f, -0.0039368710f, -0.0052269329f, 0.0066359108f, 0.0081675826f, + 0.0098046111f, 0.0115340082f, 0.0133599117f, 0.0152670480f, 0.0172310472f, + 0.0192486700f, 0.0212899297f, 0.0233421512f, 0.0253749676f, 0.0273679867f, + 0.0292957835f, 0.0311195124f, 0.0328143612f, 0.0343521908f, 0.0356939025f, + 0.0368040688f, 0.0376568660f, 0.0381996147f, 0.0384096317f, 0.0382525362f, + 0.0376743041f, 0.0366597772f, 0.0351766534f, 0.0331651047f, 0.0306228697f, + 0.0275230017f, 0.0238097552f, 0.0194889121f, 0.0145412004f, 0.0089233266f, + 0.0026506553f, -0.0042855870f, -0.0119214784f, -0.0202226657f, -0.0291852653f, + -0.0388281532f, -0.0491066054f, -0.0600038990f, -0.0715180784f, -0.0835954323f, + -0.0961983353f, -0.1093173549f, -0.1228752360f, -0.1368317008f, -0.1511485577f, + -0.1657491624f, 0.1805794984f, 0.1955795586f, 0.2106752247f, 0.2257998288f, + 0.2408826500f, 0.2558478415f, 0.2706276774f, 0.2851306200f, 0.2993004918f, + 0.3130621314f, 0.3263216913f, 0.3390280008f, 0.3511194289f, 0.3624893427f, + 0.3731132150f, 0.3829337358f, 0.3918499053f, 0.3998569846f, 0.4069095552f, + 0.4129161835f, 0.4178932011f, 0.4218119085f, 0.4245987833f, 0.4262852371f, + 0.4268692732f, 0.4262852371f, 0.4245987833f, 0.4218119085f, 0.4178932011f, + 0.4129161835f, 0.4069095552f, 0.3998569846f, 0.3918499053f, 0.3829337358f, + 0.3731132150f, 0.3624893427f, 0.3511194289f, 0.3390280008f, 0.3263216913f, + 0.3130621314f, 0.2993004918f, 0.2851306200f, 0.2706276774f, 0.2558478415f, + 0.2408826500f, 0.2257998288f, 0.2106752247f, 0.1955795586f, -0.1805794984f, + -0.1657491624f, -0.1511485577f, -0.1368317008f, -0.1228752360f, -0.1093173549f, + -0.0961983353f, -0.0835954323f, -0.0715180784f, -0.0600038990f, -0.0491066054f, + -0.0388281532f, -0.0291852653f, -0.0202226657f, -0.0119214784f, -0.0042855870f, + 0.0026506553f, 0.0089233266f, 0.0145412004f, 0.0194889121f, 0.0238097552f, + 0.0275230017f, 0.0306228697f, 0.0331651047f, 0.0351766534f, 0.0366597772f, + 0.0376743041f, 0.0382525362f, 0.0384096317f, 0.0381996147f, 0.0376568660f, + 0.0368040688f, 0.0356939025f, 0.0343521908f, 0.0328143612f, 0.0311195124f, + 0.0292957835f, 0.0273679867f, 0.0253749676f, 0.0233421512f, 0.0212899297f, + 0.0192486700f, 0.0172310472f, 0.0152670480f, 0.0133599117f, 0.0115340082f, + 0.0098046111f, 0.0081675826f, -0.0066359108f, -0.0052269329f, -0.0039368710f, + -0.0027668604f, -0.0017211447f, -0.0007941178f, 0.0000138022f, 0.0007078615f, + 0.0012910638f, 0.0017700621f, 0.0021475893f, 0.0024343103f, 0.0026357877f, + 0.0027593751f, 0.0028153569f, 0.0028110321f, 0.0027537965f, 0.0026567420f, + 0.0025196511f, 0.0023524247f, 0.0021620949f, 0.0019603714f, 0.0017474336f, + 0.0015286715f, 0.0013100877f, 0.0010990070f, 0.0008927435f, 0.0006951247f, + 0.0005170354f, 0.0003525903f, 0.0002013268f, 0.0000705295f, -0.0000446842f, + -0.0001448488f, -0.0002217961f, -0.0002845877f, -0.0003325206f, -0.0003642349f, + -0.0003836593f, -0.0003901832f, -0.0003880670f, -0.0003737023f, -0.0003578868f, + -0.0003309725f, -0.0003022735f, -0.0002733283f, -0.0002471381f, -0.0002585454f}, + + // const FLOAT32 esbr_w_16[2 * 12] = + {0.0000000000f, 0.5000000000f, 0.0000000000f, 0.5000000000f, 0.0000000000f, 0.5000000000f, + 0.1913417131f, 0.4619397521f, 0.3535533845f, 0.3535533845f, 0.4619397521f, 0.1913417131f, + 0.3535533845f, 0.3535533845f, 0.5000000000f, 0.0000000000f, 0.3535533845f, -0.3535533845f, + 0.4619397521f, 0.1913417131f, 0.3535533845f, -0.3535533845f, -0.1913417131f, -0.4619397521f}, + { + // FLOAT32 esbr_sin_cos_twiddle_l64[64] = + 0.0061357692f, 0.4999623597f, 0.4996611774f, 0.0184036121f, 0.0306603685f, 0.4990590513f, + 0.4981563091f, 0.0428986549f, 0.0551111028f, 0.4969534874f, 0.4954513311f, 0.0672903508f, + 0.0794290751f, 0.4936507046f, 0.4915527403f, 0.0915199444f, 0.1035556868f, 0.4891586900f, + 0.4864699841f, 0.1155290529f, 0.1274328232f, 0.4834882319f, 0.4802152514f, 0.1392598450f, + 0.1510029733f, 0.4766530097f, 0.4728036523f, 0.1626551449f, 0.1742093414f, 0.4686695039f, + 0.4642530382f, 0.1856586039f, 0.1969960183f, 0.4595569372f, 0.4545840025f, 0.2082147747f, + 0.2193081230f, 0.4493372440f, 0.4438198209f, 0.2302693576f, 0.2410918921f, 0.4380350411f, + 0.4319864213f, 0.2517691851f, 0.2622948289f, 0.4256775975f, 0.4191123545f, 0.2726624906f, + 0.2828659117f, 0.4122946560f, 0.4052285850f, 0.2928989232f, 0.3027555346f, 0.3979184628f, + 0.3903686106f, 0.3124297559f, 0.3219157755f, 0.3825836182f, 0.3745681942f, 0.3312079012f, + 0.3403005004f, 0.3663271368f, 0.3578654230f, 0.3491881192f, + }, + // esbr_alt_sin_twiddle_l64[32]= + { + 0.0245338380f, 0.4993977249f, 0.0490085706f, 0.4975923598f, 0.0733652338f, 0.4945882559f, + 0.0975451618f, 0.4903926253f, 0.1214900911f, 0.4850156307f, 0.1451423317f, 0.4784701765f, + 0.1684449315f, 0.4707720280f, 0.1913417131f, 0.4619397521f, 0.2137775421f, 0.4519946575f, + 0.2356983721f, 0.4409606457f, 0.2570513785f, 0.4288643003f, 0.2777851224f, 0.4157347977f, + 0.2978496552f, 0.4016037583f, 0.3171966374f, 0.3865052164f, 0.3357794881f, 0.3704755604f, + 0.3535533845f, 0.3535533845f, + }, + + // esbr_sin_cos_twiddle_l32[32] = + {0.0122706145f, 0.4998494089f, 0.4986452162f, 0.0367822833f, 0.0612053387f, 0.4962397814f, + 0.4926388264f, 0.0854809433f, 0.1095506176f, 0.4878510535f, 0.4818880260f, 0.1333563775f, + 0.1568408757f, 0.4747640789f, 0.4664964080f, 0.1799475253f, 0.2026206553f, 0.4571048915f, + 0.4466121495f, 0.2248056680f, 0.2464490980f, 0.4350434840f, 0.4224267900f, 0.2674988210f, + 0.2879040837f, 0.4087924063f, 0.3941732049f, 0.3076157868f, 0.3265864253f, 0.3786044121f, + 0.3621235490f, 0.3447702825f}, + + // esbr_alt_sin_twiddle_l32[16] = + {0.0490085706f, 0.4975923598f, 0.0975451618f, 0.4903926253f, 0.1451423317f, 0.4784701765f, + 0.1913417131f, 0.4619397521f, 0.2356983721f, 0.4409606457f, 0.2777851224f, 0.4157347977f, + 0.3171966374f, 0.3865052164f, 0.3535533845f, 0.3535533845f}, + + // esbr_t_cos_sin_l32[32+32] = //exp[-i * pi/32* 3/4 * (k +0.5)] + { + + 0.4996611774f, 0.0184036121f, 0.4969534874f, 0.0551111028f, 0.4915527403f, + 0.0915199444f, 0.4834882319f, 0.1274328232f, 0.4728036523f, 0.1626551449f, + 0.4595569372f, 0.1969960183f, 0.4438198209f, 0.2302693576f, 0.4256775975f, + 0.2622948289f, 0.4052285850f, 0.2928989232f, 0.3825836182f, 0.3219157755f, + 0.3578654230f, 0.3491881192f, 0.3312079012f, 0.3745681942f, 0.3027555346f, + 0.3979184628f, 0.2726624906f, 0.4191123545f, 0.2410918921f, 0.4380350411f, + 0.2082147747f, 0.4545840025f, 0.1742093414f, 0.4686695039f, 0.1392598450f, + 0.4802152514f, 0.1035556868f, 0.4891586900f, 0.0672903508f, 0.4954513311f, + 0.0306603685f, 0.4990590513f, -0.0061357692f, 0.4999623597f, -0.0428986549f, + 0.4981563091f, -0.0794290751f, 0.4936507046f, -0.1155290529f, 0.4864699841f, + -0.1510029733f, 0.4766530097f, -0.1856586039f, 0.4642530382f, -0.2193081230f, + 0.4493372440f, -0.2517691851f, 0.4319864213f, -0.2828659117f, 0.4122946560f, + -0.3124297559f, 0.3903686106f, -0.3403005004f, 0.3663271368f}, + {0.0163595416f, 0.4997322857f, 0.4975923598f, 0.0490085706f, 0.0814477354f, 0.4933216572f, + 0.4869384766f, 0.1135381311f, 0.1451423317f, 0.4784701765f, 0.4679529667f, 0.1761250198f, + 0.2063535154f, 0.4554319084f, 0.4409606457f, 0.2356983721f, 0.2640339136f, 0.4246010780f, + 0.4064233303f, 0.2912388444f, 0.3171966374f, 0.3865052164f, 0.3649320304f, 0.3417961597f}, + {0.0652630925f, 0.4957224429f, 0.1294095218f, 0.4829629064f, 0.1913417131f, 0.4619397521f, + 0.2500000000f, 0.4330126941f, 0.3043807149f, 0.3966766596f, 0.3535533845f, 0.3535533845f}, + {0.4994938970f, 0.0224907938f, 0.4954513311f, 0.0672903508f, 0.4873988628f, 0.1115453094f, + 0.4754016995f, 0.1548974812f, 0.4595569372f, 0.1969960183f, 0.4399927855f, 0.2375001907f, + 0.4168676436f, 0.2760821879f, 0.3903686106f, 0.3124297559f, 0.3607102036f, 0.3462486863f, + 0.3281324208f, 0.3772653341f, 0.2928989232f, 0.4052285850f, 0.2552949190f, 0.4299122095f, + 0.2156246901f, 0.4511163831f, 0.1742093414f, 0.4686695039f, 0.1313840449f, 0.4824295044f, + 0.0874954164f, 0.4922850430f, 0.0428986549f, 0.4981563091f, -0.0020453020f, 0.4999958277f, + -0.0469727069f, 0.4977886677f, -0.0915199444f, 0.4915527403f, -0.1353264749f, 0.4813385010f, + -0.1780377626f, 0.4672285914f, -0.2193081230f, 0.4493372440f, -0.2588035464f, 0.4278092086f}, + + {0.0245338380f, 0.4993977249f, 0.4945882559f, 0.0733652338f, 0.1214900911f, 0.4850156307f, + 0.4707720280f, 0.1684449315f, 0.2137775421f, 0.4519946575f, 0.4288643003f, 0.2570513785f, + 0.2978496552f, 0.4016037583f, 0.3704755604f, 0.3357794881f}, + + {0.0975451618f, 0.4903926253f, 0.1913417131f, 0.4619397521f, 0.2777851224f, 0.4157347977f, + 0.3535533845f, 0.3535533845f}, + + {0.4990590513f, 0.0306603685f, 0.4915527403f, 0.0915199444f, 0.4766530097f, 0.1510029733f, + 0.4545840025f, 0.2082147747f, 0.4256775975f, 0.2622948289f, 0.3903686106f, 0.3124297559f, + 0.3491881192f, 0.3578654230f, 0.3027555346f, 0.3979184628f, 0.2517691851f, 0.4319864213f, + 0.1969960183f, 0.4595569372f, 0.1392598450f, 0.4802152514f, 0.0794290751f, 0.4936507046f, + 0.0184036121f, 0.4996611774f, -0.0428986549f, 0.4981563091f, -0.1035556868f, 0.4891586900f, + -0.1626551449f, 0.4728036523f}}; const FLOAT32 long_window_sine_ld_64[IXHEAACE_QMF_CHANNELS] = { 0.013038467f, 0.037573683f, 0.062086265f, 0.086561449f, 0.110984492f, 0.135340682f, diff --git a/encoder/ixheaace_sbr_ton_corr.c b/encoder/ixheaace_sbr_ton_corr.c index 559dc76..ca623fa 100644 --- a/encoder/ixheaace_sbr_ton_corr.c +++ b/encoder/ixheaace_sbr_ton_corr.c @@ -45,6 +45,8 @@ #include "ixheaace_sbr_inv_filtering_estimation.h" #include "ixheaace_sbr_noise_floor_est.h" #include "ixheaace_sbr_ton_corr.h" +#include "iusace_esbr_pvc.h" +#include "iusace_esbr_inter_tes.h" #include "ixheaace_sbr.h" #include "ixheaace_sbr_misc.h" @@ -225,7 +227,6 @@ static IA_ERRORCODE ia_enhaacplus_enc_reset_patch(ixheaace_pstr_sbr_ton_corr_est if (ixheaac_abs32(target_stop_band - goal_sb) < 3) { goal_sb = usb; } - patch++; } diff --git a/encoder/ixheaace_sbr_ton_corr_hp.c b/encoder/ixheaace_sbr_ton_corr_hp.c index b9ff08b..9041b56 100644 --- a/encoder/ixheaace_sbr_ton_corr_hp.c +++ b/encoder/ixheaace_sbr_ton_corr_hp.c @@ -44,6 +44,8 @@ #include "ixheaace_sbr_inv_filtering_estimation.h" #include "ixheaace_sbr_noise_floor_est.h" #include "ixheaace_sbr_ton_corr.h" +#include "iusace_esbr_pvc.h" +#include "iusace_esbr_inter_tes.h" #include "ixheaace_sbr.h" #include "ixheaace_sbr_misc.h" diff --git a/encoder/ixheaace_sbr_tran_det.c b/encoder/ixheaace_sbr_tran_det.c index daef418..cf9bce4 100644 --- a/encoder/ixheaace_sbr_tran_det.c +++ b/encoder/ixheaace_sbr_tran_det.c @@ -207,11 +207,20 @@ ixheaace_frame_splitter(FLOAT32 **ptr_energies, VOID ixheaace_create_sbr_transient_detector( ixheaace_pstr_sbr_trans_detector pstr_sbr_trans_detector, WORD32 sample_freq, WORD32 total_bitrate, WORD32 codec_bitrate, WORD32 tran_thr, WORD32 mode, WORD32 tran_fc, - WORD32 frame_flag_480, WORD32 is_ld_sbr, WORD32 start_band) { + WORD32 frame_flag_480, WORD32 is_ld_sbr, WORD32 sbr_ratio_idx, + ixheaace_sbr_codec_type sbr_codec, WORD32 start_band) { WORD32 no_cols = 32, buffer_length = 96; FLOAT32 br_fac; FLOAT32 frm_dur = 2048.0f / (FLOAT32)sample_freq; FLOAT32 split_thr_fac = frm_dur - 0.01f; + if ((sbr_codec == USAC_SBR) && (sbr_ratio_idx == USAC_SBR_RATIO_INDEX_4_1)) { + frm_dur = frm_dur * 2; + split_thr_fac = frm_dur - 0.01f; + } + if ((1 == is_ld_sbr) && (1 == frame_flag_480)) { + no_cols = 30; + buffer_length = 90; + } memset(pstr_sbr_trans_detector, 0, sizeof(ixheaace_str_sbr_trans_detector)); diff --git a/encoder/ixheaace_sbr_tran_det.h b/encoder/ixheaace_sbr_tran_det.h index 5a0ac68..94dd3a5 100644 --- a/encoder/ixheaace_sbr_tran_det.h +++ b/encoder/ixheaace_sbr_tran_det.h @@ -66,7 +66,8 @@ VOID ixheaace_detect_transient_eld(FLOAT32 **ptr_energies, VOID ixheaace_create_sbr_transient_detector( ixheaace_pstr_sbr_trans_detector pstr_sbr_trans_detector, WORD32 sample_freq, WORD32 total_bitrate, WORD32 codec_bitrate, WORD32 tran_thr, WORD32 mode, WORD32 tran_fc, - WORD32 frame_flag_480, WORD32 is_ld_sbr, WORD32 start_band); + WORD32 frame_flag_480, WORD32 is_ld_sbr, WORD32 sbr_ratio_idx, + ixheaace_sbr_codec_type sbr_codec, WORD32 start_band); IA_ERRORCODE ixheaace_frame_splitter(FLOAT32 **ptr_energies, diff --git a/encoder/ixheaace_sbr_write_bitstream.c b/encoder/ixheaace_sbr_write_bitstream.c index b03d1ad..5482382 100644 --- a/encoder/ixheaace_sbr_write_bitstream.c +++ b/encoder/ixheaace_sbr_write_bitstream.c @@ -45,8 +45,11 @@ #include "ixheaace_sbr_noise_floor_est.h" #include "ixheaace_sbr_ton_corr.h" +#include "iusace_esbr_pvc.h" +#include "iusace_esbr_inter_tes.h" #include "ixheaace_sbr.h" #include "ixheaace_sbr_cmondata.h" +#include "iusace_esbr_pvc.h" #include "ixheaace_sbr_hybrid.h" #include "ixheaace_sbr_ps_enc.h" @@ -99,7 +102,48 @@ static WORD32 ixheaace_get_esbr_ext_data_size(ixheaace_str_esbr_bs_data *pstr_es } return num_bits; } +static WORD32 iusace_encode_pvc_envelope(ixheaace_bit_buf_handle pstr_bs_handle, + ixheaace_pvc_bs_info *pstr_pvc_bs_data, + WORD32 usac_indep_flag) { + WORD32 payload_cnt_bits = 0; + payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_pvc_bs_data->div_mode, + IXHEAACE_ESBR_PVC_DIV_MODE_BITS); + payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_pvc_bs_data->ns_mode, + IXHEAACE_ESBR_PVC_NS_MODE_BITS); + if (0 == pstr_pvc_bs_data->div_mode) { + if (1 == usac_indep_flag) { + payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_pvc_bs_data->pvc_id_bs[0], + IXHEAACE_ESBR_PVC_ID_BITS); + } else { + if (1 == pstr_pvc_bs_data->grid_info[0]) { + payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, 0, IXHEAACE_ESBR_PVC_REUSE_BITS); + payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_pvc_bs_data->pvc_id_bs[0], + IXHEAACE_ESBR_PVC_ID_BITS); + } else { + payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, 1, IXHEAACE_ESBR_PVC_REUSE_BITS); + } + } + } else if (pstr_pvc_bs_data->div_mode <= 3) { + /* Do nothing */ + } else { + WORD32 gi, is_grid_info; + for (gi = 0; gi < pstr_pvc_bs_data->num_grid_info; gi++) { + if (gi == 0 && 1 == usac_indep_flag) { + is_grid_info = 1; + } else { + is_grid_info = pstr_pvc_bs_data->grid_info[gi]; + payload_cnt_bits += + ixheaace_write_bits(pstr_bs_handle, is_grid_info, IXHEAACE_ESBR_PVC_GRID_INFO_BITS); + } + if (is_grid_info) { + payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_pvc_bs_data->pvc_id_bs[gi], + IXHEAACE_ESBR_PVC_ID_BITS); + } + } + } + return payload_cnt_bits; +} static WORD32 ia_enhaacplus_enc_ceil_ln2(WORD32 x) { WORD32 tmp = -1; @@ -157,7 +201,6 @@ static WORD32 ixheaace_encode_sbr_grid(ixheaace_pstr_sbr_env_data pstr_sbr_env_i payload_cnt_bits += ixheaace_write_bits( pstr_bs_handle, pstr_sbr_env_info->pstr_sbr_bs_grid->p, (UWORD8)tmp_var); - /* pstr_sbr_env_info->pstr_sbr_bs_grid->v_f[] */ for (i = 0; i < pstr_sbr_env_info->pstr_sbr_bs_grid->n + 1; i++) { payload_cnt_bits += ixheaace_write_bits( pstr_bs_handle, pstr_sbr_env_info->pstr_sbr_bs_grid->v_f[i], SBR_RES_BITS); @@ -253,27 +296,49 @@ static WORD32 ixheaace_encode_sbr_grid(ixheaace_pstr_sbr_env_data pstr_sbr_env_i static WORD32 ixheaace_encode_sbr_dtdf(ixheaace_pstr_sbr_env_data pstr_sbr_env_info, ixheaace_bit_buf_handle pstr_bs_handle, - ixheaace_sbr_codec_type sbr_codec) { + ixheaace_sbr_codec_type sbr_codec, WORD32 usac_indep_flag, + WORD32 sbr_pvc_mode) { WORD32 i, payload_cnt_bits = 0, num_of_noise_env; num_of_noise_env = (pstr_sbr_env_info->no_of_envelopes > 1) ? 2 : 1; if (USAC_SBR != sbr_codec) { - /* pstr_sbr_env_info->domain_vec[] */ for (i = 0; i < pstr_sbr_env_info->no_of_envelopes; ++i) { payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_info->domain_vec[i], SBR_DIR_BITS); } } + else { + if (sbr_pvc_mode == 0) { + WORD32 start_env = 0; + if (1 == usac_indep_flag) { + start_env = 1; + } + for (i = start_env; i < pstr_sbr_env_info->no_of_envelopes; ++i) { + payload_cnt_bits += + ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_info->domain_vec[i], SBR_DIR_BITS); + } + } else { + /* Do nothing */ + } + } if (USAC_SBR != sbr_codec) { - /* pstr_sbr_env_info->domain_vec_noise[] */ for (i = 0; i < num_of_noise_env; ++i) { payload_cnt_bits += ixheaace_write_bits( pstr_bs_handle, pstr_sbr_env_info->domain_vec_noise[i], SBR_DIR_BITS); } - } + } else { + WORD32 start_env = 0; + if (1 == usac_indep_flag) { + start_env = 1; + } + for (i = start_env; i < num_of_noise_env; ++i) { + payload_cnt_bits += ixheaace_write_bits( + pstr_bs_handle, pstr_sbr_env_info->domain_vec_noise[i], SBR_DIR_BITS); + } + } return payload_cnt_bits; } @@ -374,7 +439,8 @@ static WORD32 ixheaace_write_noise_lvl_data(ixheaace_pstr_sbr_env_data pstr_sbr_ static IA_ERRORCODE ixheaace_write_env_data(ixheaace_pstr_sbr_env_data pstr_sbr_env_info, ixheaace_bit_buf_handle pstr_bs_handle, - WORD32 coupling, WORD32 *ptr_payload_cnt_bits) { + WORD32 coupling, ixheaace_sbr_codec_type sbr_codec, + WORD32 *ptr_payload_cnt_bits) { WORD32 j, i, delta; *ptr_payload_cnt_bits = 0; @@ -461,13 +527,27 @@ static IA_ERRORCODE ixheaace_write_env_data(ixheaace_pstr_sbr_env_data pstr_sbr_ } } } + if (USAC_SBR == sbr_codec) { + if (1 == pstr_sbr_env_info->sbr_inter_tes) { + *ptr_payload_cnt_bits += + ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_info->ptr_sbr_inter_tes_shape[j], + IXHEAACE_SBR_TES_SHAPE_BITS); + if (1 == pstr_sbr_env_info->ptr_sbr_inter_tes_shape[j]) { + *ptr_payload_cnt_bits += ixheaace_write_bits( + pstr_bs_handle, pstr_sbr_env_info->ptr_sbr_inter_tes_shape_mode[j], + IXHEAACE_SBR_TES_SHAPE_MODE_BITS); + } + } + } } return IA_NO_ERROR; } static WORD32 ixheaace_write_synthetic_coding_data(ixheaace_pstr_sbr_env_data pstr_sbr_env_info, - ixheaace_bit_buf_handle pstr_bs_handle) + ixheaace_bit_buf_handle pstr_bs_handle, + ixheaace_sbr_codec_type sbr_codec, + WORD32 sbr_pvc_mode) { WORD32 i; @@ -477,13 +557,19 @@ static WORD32 ixheaace_write_synthetic_coding_data(ixheaace_pstr_sbr_env_data ps ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_info->add_harmonic_flag, 1); if (pstr_sbr_env_info->add_harmonic_flag) { - /* pstr_sbr_env_info->add_harmonic[] */ for (i = 0; i < pstr_sbr_env_info->no_harmonics; i++) { payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_info->add_harmonic[i], 1); } } - + if (USAC_SBR == sbr_codec && 0 != sbr_pvc_mode) { + if (pstr_sbr_env_info->sbr_sinusoidal_pos_flag) { + payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, 1, 1); + payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, 31, 5); + } else { + payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, 0, 1); + } + } return payload_cnt_bits; } @@ -497,10 +583,32 @@ static IA_ERRORCODE ixheaace_encode_sbr_single_channel_element( if (sbr_codec != USAC_SBR) { payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, 0, 1); + } else { + if (pstr_sbr_env_info->harmonic_sbr) { + // USAC Harmonic SBR data + payload_cnt_bits += + ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_info->sbr_patching_mode, 1); + if (0 == pstr_sbr_env_info->sbr_patching_mode) { + payload_cnt_bits += + ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_info->sbr_oversampling_flag, 1); + payload_cnt_bits += + ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_info->sbr_pitchin_bins_flag, 1); + if (0 != pstr_sbr_env_info->sbr_pitchin_bins_flag) { + payload_cnt_bits += + ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_info->sbr_pitchin_bins, 7); + } + } + } } - payload_cnt_bits += ixheaace_encode_sbr_grid(pstr_sbr_env_info, pstr_bs_handle, sbr_codec); - { payload_cnt_bits += ixheaace_encode_sbr_dtdf(pstr_sbr_env_info, pstr_bs_handle, sbr_codec); } + if (sbr_codec == USAC_SBR) { + payload_cnt_bits += ixheaace_encode_sbr_dtdf(pstr_sbr_env_info, pstr_bs_handle, sbr_codec, + pstr_sbr_env_info->usac_indep_flag, + pstr_sbr_env_info->sbr_pvc_mode); + } else { + payload_cnt_bits += + ixheaace_encode_sbr_dtdf(pstr_sbr_env_info, pstr_bs_handle, sbr_codec, 0, 0); + } { WORD32 i; @@ -509,23 +617,39 @@ static IA_ERRORCODE ixheaace_encode_sbr_single_channel_element( pstr_bs_handle, pstr_sbr_env_info->sbr_invf_mode_vec[i], SI_SBR_INVF_MODE_BITS); } } - - { + if (sbr_codec != USAC_SBR) { WORD32 env_data_len; - err_code = ixheaace_write_env_data(pstr_sbr_env_info, pstr_bs_handle, 0, &env_data_len); + err_code = + ixheaace_write_env_data(pstr_sbr_env_info, pstr_bs_handle, 0, sbr_codec, &env_data_len); if (err_code) { *ptr_num_bits = payload_cnt_bits; return err_code; } payload_cnt_bits += env_data_len; + } else { + if (0 == pstr_sbr_env_info->sbr_pvc_mode) { + WORD32 env_data_len; + err_code = + ixheaace_write_env_data(pstr_sbr_env_info, pstr_bs_handle, 0, sbr_codec, &env_data_len); + if (err_code) { + *ptr_num_bits = payload_cnt_bits; + return err_code; + } + payload_cnt_bits += env_data_len; + } else { + // PVC envelope goes here + payload_cnt_bits += iusace_encode_pvc_envelope(pstr_bs_handle, &pstr_sbr_env_info->pvc_info, + pstr_sbr_env_info->usac_indep_flag); + } } - payload_cnt_bits += ixheaace_write_noise_lvl_data(pstr_sbr_env_info, pstr_bs_handle, 0); if (USAC_SBR == sbr_codec) { - payload_cnt_bits += ixheaace_write_synthetic_coding_data(pstr_sbr_env_info, pstr_bs_handle); + payload_cnt_bits += ixheaace_write_synthetic_coding_data( + pstr_sbr_env_info, pstr_bs_handle, sbr_codec, pstr_sbr_env_info->sbr_pvc_mode); } else { - payload_cnt_bits += ixheaace_write_synthetic_coding_data(pstr_sbr_env_info, pstr_bs_handle); + payload_cnt_bits += + ixheaace_write_synthetic_coding_data(pstr_sbr_env_info, pstr_bs_handle, sbr_codec, 0); } *ptr_num_bits = payload_cnt_bits; @@ -548,22 +672,39 @@ static IA_ERRORCODE ixheaace_encode_sbr_channel_pair_element( payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, coupling, SI_SBR_COUPLING_BITS); if (coupling) { + if (sbr_codec == USAC_SBR && pstr_sbr_env_data_left->harmonic_sbr) { + // USAC Harmonic SBR data + payload_cnt_bits += + ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_data_left->sbr_patching_mode, 1); + if (0 == pstr_sbr_env_data_left->sbr_patching_mode) { + payload_cnt_bits += + ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_data_left->sbr_oversampling_flag, 1); + payload_cnt_bits += + ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_data_left->sbr_pitchin_bins_flag, 1); + if (0 != pstr_sbr_env_data_left->sbr_pitchin_bins_flag) { + payload_cnt_bits += + ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_data_left->sbr_pitchin_bins, 7); + } + } + } payload_cnt_bits += ixheaace_encode_sbr_grid(pstr_sbr_env_data_left, pstr_bs_handle, sbr_codec); payload_cnt_bits += - ixheaace_encode_sbr_dtdf(pstr_sbr_env_data_left, pstr_bs_handle, sbr_codec); + ixheaace_encode_sbr_dtdf(pstr_sbr_env_data_left, pstr_bs_handle, sbr_codec, + pstr_sbr_env_data_left->usac_indep_flag, 0); payload_cnt_bits += - ixheaace_encode_sbr_dtdf(pstr_sbr_env_data_right, pstr_bs_handle, sbr_codec); + ixheaace_encode_sbr_dtdf(pstr_sbr_env_data_right, pstr_bs_handle, sbr_codec, + pstr_sbr_env_data_left->usac_indep_flag, 0); - /* pstr_sbr_env_data_left->sbr_invf_mode_vec[] */ for (i = 0; i < pstr_sbr_env_data_left->noise_band_count; i++) { payload_cnt_bits += ixheaace_write_bits( pstr_bs_handle, pstr_sbr_env_data_left->sbr_invf_mode_vec[i], SI_SBR_INVF_MODE_BITS); } - err_code = ixheaace_write_env_data(pstr_sbr_env_data_left, pstr_bs_handle, 1, &env_data_len); + err_code = ixheaace_write_env_data(pstr_sbr_env_data_left, pstr_bs_handle, 1, sbr_codec, + &env_data_len); if (err_code) { *ptr_num_bits = payload_cnt_bits; return err_code; @@ -573,7 +714,8 @@ static IA_ERRORCODE ixheaace_encode_sbr_channel_pair_element( payload_cnt_bits += ixheaace_write_noise_lvl_data(pstr_sbr_env_data_left, pstr_bs_handle, 1); - err_code = ixheaace_write_env_data(pstr_sbr_env_data_right, pstr_bs_handle, 1, &env_data_len); + err_code = ixheaace_write_env_data(pstr_sbr_env_data_right, pstr_bs_handle, 1, sbr_codec, + &env_data_len); if (err_code) { *ptr_num_bits = payload_cnt_bits; return err_code; @@ -582,12 +724,40 @@ static IA_ERRORCODE ixheaace_encode_sbr_channel_pair_element( payload_cnt_bits += ixheaace_write_noise_lvl_data(pstr_sbr_env_data_right, pstr_bs_handle, 1); - payload_cnt_bits += - ixheaace_write_synthetic_coding_data(pstr_sbr_env_data_left, pstr_bs_handle); + payload_cnt_bits += ixheaace_write_synthetic_coding_data(pstr_sbr_env_data_left, + pstr_bs_handle, sbr_codec, 0); - payload_cnt_bits += - ixheaace_write_synthetic_coding_data(pstr_sbr_env_data_right, pstr_bs_handle); + payload_cnt_bits += ixheaace_write_synthetic_coding_data(pstr_sbr_env_data_right, + pstr_bs_handle, sbr_codec, 0); } else { + if (sbr_codec == USAC_SBR && pstr_sbr_env_data_left->harmonic_sbr) { + // USAC Harmonic SBR data + payload_cnt_bits += + ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_data_left->sbr_patching_mode, 1); + if (0 == pstr_sbr_env_data_left->sbr_patching_mode) { + payload_cnt_bits += + ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_data_left->sbr_oversampling_flag, 1); + payload_cnt_bits += + ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_data_left->sbr_pitchin_bins_flag, 1); + if (0 != pstr_sbr_env_data_left->sbr_pitchin_bins_flag) { + payload_cnt_bits += + ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_data_left->sbr_pitchin_bins, 7); + } + } + + payload_cnt_bits += + ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_data_right->sbr_patching_mode, 1); + if (0 == pstr_sbr_env_data_right->sbr_patching_mode) { + payload_cnt_bits += ixheaace_write_bits( + pstr_bs_handle, pstr_sbr_env_data_right->sbr_oversampling_flag, 1); + payload_cnt_bits += ixheaace_write_bits( + pstr_bs_handle, pstr_sbr_env_data_right->sbr_pitchin_bins_flag, 1); + if (0 != pstr_sbr_env_data_right->sbr_pitchin_bins_flag) { + payload_cnt_bits += + ixheaace_write_bits(pstr_bs_handle, pstr_sbr_env_data_right->sbr_pitchin_bins, 7); + } + } + } payload_cnt_bits += ixheaace_encode_sbr_grid(pstr_sbr_env_data_left, pstr_bs_handle, sbr_codec); @@ -595,31 +765,33 @@ static IA_ERRORCODE ixheaace_encode_sbr_channel_pair_element( ixheaace_encode_sbr_grid(pstr_sbr_env_data_right, pstr_bs_handle, sbr_codec); payload_cnt_bits += - ixheaace_encode_sbr_dtdf(pstr_sbr_env_data_left, pstr_bs_handle, sbr_codec); + ixheaace_encode_sbr_dtdf(pstr_sbr_env_data_left, pstr_bs_handle, sbr_codec, + pstr_sbr_env_data_left->usac_indep_flag, 0); payload_cnt_bits += - ixheaace_encode_sbr_dtdf(pstr_sbr_env_data_right, pstr_bs_handle, sbr_codec); + ixheaace_encode_sbr_dtdf(pstr_sbr_env_data_right, pstr_bs_handle, sbr_codec, + pstr_sbr_env_data_left->usac_indep_flag, 0); - /* pstr_sbr_env_data_left->sbr_invf_mode_vec[] */ for (i = 0; i < pstr_sbr_env_data_left->noise_band_count; i++) { payload_cnt_bits += ixheaace_write_bits( pstr_bs_handle, pstr_sbr_env_data_left->sbr_invf_mode_vec[i], SI_SBR_INVF_MODE_BITS); } - /* pstr_sbr_env_data_right->sbr_invf_mode_vec[] */ for (i = 0; i < pstr_sbr_env_data_right->noise_band_count; i++) { payload_cnt_bits += ixheaace_write_bits( pstr_bs_handle, pstr_sbr_env_data_right->sbr_invf_mode_vec[i], SI_SBR_INVF_MODE_BITS); } - err_code = ixheaace_write_env_data(pstr_sbr_env_data_left, pstr_bs_handle, 0, &env_data_len); + err_code = ixheaace_write_env_data(pstr_sbr_env_data_left, pstr_bs_handle, 0, sbr_codec, + &env_data_len); if (err_code) { *ptr_num_bits = payload_cnt_bits; return err_code; } payload_cnt_bits += env_data_len; - err_code = ixheaace_write_env_data(pstr_sbr_env_data_right, pstr_bs_handle, 0, &env_data_len); + err_code = ixheaace_write_env_data(pstr_sbr_env_data_right, pstr_bs_handle, 0, sbr_codec, + &env_data_len); if (err_code) { *ptr_num_bits = payload_cnt_bits; return err_code; @@ -630,11 +802,11 @@ static IA_ERRORCODE ixheaace_encode_sbr_channel_pair_element( payload_cnt_bits += ixheaace_write_noise_lvl_data(pstr_sbr_env_data_right, pstr_bs_handle, 0); - payload_cnt_bits += - ixheaace_write_synthetic_coding_data(pstr_sbr_env_data_left, pstr_bs_handle); + payload_cnt_bits += ixheaace_write_synthetic_coding_data(pstr_sbr_env_data_left, + pstr_bs_handle, sbr_codec, 0); - payload_cnt_bits += - ixheaace_write_synthetic_coding_data(pstr_sbr_env_data_right, pstr_bs_handle); + payload_cnt_bits += ixheaace_write_synthetic_coding_data(pstr_sbr_env_data_right, + pstr_bs_handle, sbr_codec, 0); } *ptr_num_bits = payload_cnt_bits; @@ -935,7 +1107,7 @@ static WORD32 ixheaace_encode_sbr_header_data(ixheaace_pstr_sbr_hdr_data pstr_sb payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->sbr_smoothing_length, SI_SBR_SMOOTHING_LENGTH_BITS); } - } /* pstr_sbr_hdr != NULL_PTR */ + } return payload_cnt_bits; } @@ -964,7 +1136,100 @@ static WORD32 ia_enhaacplus_enc_encode_sbr_header(ixheaace_pstr_sbr_hdr_data pst return payload_cnt_bits; } +static WORD32 iusace_encode_sbr_header_data(ixheaace_pstr_sbr_hdr_data pstr_sbr_hdr, + ixheaace_bit_buf_handle pstr_bs_handle) { + WORD32 payload_cnt_bits = 0; + if (pstr_sbr_hdr != NULL_PTR) { + payload_cnt_bits += + ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->sbr_start_freq, SI_SBR_START_FREQ_BITS); + + payload_cnt_bits += + ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->sbr_stop_freq, SI_SBR_STOP_FREQ_BITS); + + payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->header_extra_1, + SI_SBR_HEADER_EXTRA_1_BITS); + + payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->header_extra_2, + SI_SBR_HEADER_EXTRA_2_BITS); + + if (pstr_sbr_hdr->header_extra_1) { + payload_cnt_bits += + ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->freq_scale, SI_SBR_FREQ_SCALE_BITS); + + payload_cnt_bits += + ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->alter_scale, SI_SBR_ALTER_SCALE_BITS); + + payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->sbr_noise_bands, + SI_SBR_NOISE_BANDS_BITS); + } + + if (pstr_sbr_hdr->header_extra_2) { + payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->sbr_limiter_bands, + SI_SBR_LIMITER_BANDS_BITS); + + payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->sbr_limiter_gains, + SI_SBR_LIMITER_GAINS_BITS); + + payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->sbr_interpol_freq, + SI_SBR_INTERPOL_FREQ_BITS); + + payload_cnt_bits += ixheaace_write_bits(pstr_bs_handle, pstr_sbr_hdr->sbr_smoothing_length, + SI_SBR_SMOOTHING_LENGTH_BITS); + } + } + + return payload_cnt_bits; +} + +static WORD32 ia_usac_enc_encode_sbr_header(ixheaace_pstr_sbr_hdr_data pstr_sbr_hdr, + ixheaace_pstr_sbr_bitstream_data pstr_sbr_bs, + ixheaace_pstr_common_data pstr_cmon_data) { + WORD32 payload_cnt_bits = 0; + WORD32 sbr_info_flag = 0; + WORD32 sbr_hdr_flag = 0; + if (pstr_sbr_bs->usac_indep_flag) { + sbr_hdr_flag = 1; + sbr_info_flag = 1; + } else { + if (pstr_sbr_bs->header_active) { + sbr_info_flag = 1; + payload_cnt_bits += ixheaace_write_bits(&pstr_cmon_data->str_sbr_bit_buf, 1, 1); + sbr_hdr_flag = 1; + payload_cnt_bits += ixheaace_write_bits(&pstr_cmon_data->str_sbr_bit_buf, 1, 1); + } else { + payload_cnt_bits += ixheaace_write_bits(&pstr_cmon_data->str_sbr_bit_buf, 0, 1); + } + } + + if (1 == sbr_info_flag) { + payload_cnt_bits += + ixheaace_write_bits(&pstr_cmon_data->str_sbr_bit_buf, pstr_sbr_hdr->sbr_amp_res, 1); + + payload_cnt_bits += + ixheaace_write_bits(&pstr_cmon_data->str_sbr_bit_buf, pstr_sbr_hdr->sbr_xover_band, 4); + + payload_cnt_bits += + ixheaace_write_bits(&pstr_cmon_data->str_sbr_bit_buf, pstr_sbr_hdr->sbr_pre_proc, 1); + if (pstr_sbr_hdr->sbr_pvc_active) { + payload_cnt_bits += + ixheaace_write_bits(&pstr_cmon_data->str_sbr_bit_buf, pstr_sbr_hdr->sbr_pvc_mode, 2); + } + } + + if (1 == sbr_hdr_flag) { + WORD32 sbr_def_hdr = 0; + // SBR default header + payload_cnt_bits += ixheaace_write_bits(&pstr_cmon_data->str_sbr_bit_buf, sbr_def_hdr, 1); + if (0 == sbr_def_hdr) { + payload_cnt_bits += + iusace_encode_sbr_header_data(pstr_sbr_hdr, &pstr_cmon_data->str_sbr_bit_buf); + } + } + pstr_cmon_data->sbr_hdr_bits = payload_cnt_bits; + + return payload_cnt_bits; +} IA_ERRORCODE ixheaace_write_env_single_channel_element( ixheaace_pstr_sbr_hdr_data pstr_sbr_hdr, ixheaace_pstr_sbr_bitstream_data pstr_sbr_bs, @@ -981,7 +1246,10 @@ ixheaace_write_env_single_channel_element( pstr_cmon_data->sbr_crc_len = 0; if (pstr_sbr_env_info != NULL_PTR) { - { + if (USAC_SBR == sbr_codec) { + payload_cnt_bits += + ia_usac_enc_encode_sbr_header(pstr_sbr_hdr, pstr_sbr_bs, pstr_cmon_data); + } else { /* write header */ payload_cnt_bits += ia_enhaacplus_enc_encode_sbr_header(pstr_sbr_hdr, pstr_sbr_bs, pstr_cmon_data); @@ -1020,7 +1288,10 @@ ixheaace_write_env_channel_pair_element( /* write pure SBR data */ if ((pstr_sbr_env_data_left != NULL_PTR) && (pstr_sbr_env_data_right != NULL_PTR)) { - { + if (USAC_SBR == sbr_codec) { + payload_cnt_bits += + ia_usac_enc_encode_sbr_header(pstr_sbr_hdr, pstr_sbr_bs, pstr_cmon_data); + } else { /* write header */ payload_cnt_bits += ia_enhaacplus_enc_encode_sbr_header(pstr_sbr_hdr, pstr_sbr_bs, pstr_cmon_data); diff --git a/encoder/ixheaace_sf_estimation.c b/encoder/ixheaace_sf_estimation.c index 9d660ff..a94a6dd 100644 --- a/encoder/ixheaace_sf_estimation.c +++ b/encoder/ixheaace_sf_estimation.c @@ -223,9 +223,7 @@ static FLOAT32 iaace_calc_sfb_dist(const FLOAT32 *ptr_spec, const FLOAT32 *ptr_e FLOAT32 dist = 0; FLOAT32 k = -0.0946f + 0.5f; FLOAT32 quantizer = ixheaace_fd_quant_table[gain + 128]; - ; FLOAT32 inv_quantizer = ixheaace_fd_inv_quant_table[gain + 128]; - ; while (i < sfb_width) { FLOAT32 iq_val; @@ -322,7 +320,7 @@ static VOID iaace_assimilate_single_scf(ixheaace_psy_out_channel *pstr_psy_out, FLOAT32 *ptr_sfb_num_lines, WORD16 *ptr_min_calc_scf, FLOAT32 *ptr_ptr_mdct_spec) { WORD32 sfb_prev, sfb_act, sfb_next; - WORD16 scf_act, *scf_prev, *scf_next, min_scf, max_scf; + WORD16 scf_act = 0, *scf_prev, *scf_next, min_scf, max_scf; WORD32 sfb_width, sfb_offs; FLOAT32 energy; FLOAT32 sfb_pe_prev, sfb_pe_new; @@ -688,10 +686,12 @@ VOID iaace_estimate_scfs_chan( for (j = 0; j < pstr_psy_out_chan->sfb_offsets[i + 1] - pstr_psy_out_chan->sfb_offsets[i]; j++) { - ptr_exp_spec[pstr_psy_out_chan->sfb_offsets[i] + j] = (FLOAT32)( - pstr_psy_out_chan->ptr_spec_coeffs[pstr_psy_out_chan->sfb_offsets[i] + j]); - ptr_mdct_spec[pstr_psy_out_chan->sfb_offsets[i] + j] = (FLOAT32)( - pstr_psy_out_chan->ptr_spec_coeffs[pstr_psy_out_chan->sfb_offsets[i] + j]); + ptr_exp_spec[pstr_psy_out_chan->sfb_offsets[i] + j] = + (FLOAT32)(pstr_psy_out_chan + ->ptr_spec_coeffs[pstr_psy_out_chan->sfb_offsets[i] + j]); + ptr_mdct_spec[pstr_psy_out_chan->sfb_offsets[i] + j] = + (FLOAT32)(pstr_psy_out_chan + ->ptr_spec_coeffs[pstr_psy_out_chan->sfb_offsets[i] + j]); } iaace_calculate_exp_spec( diff --git a/encoder/ixheaace_signal_classifier.c b/encoder/ixheaace_signal_classifier.c new file mode 100644 index 0000000..9705d06 --- /dev/null +++ b/encoder/ixheaace_signal_classifier.c @@ -0,0 +1,1077 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ +#include +#include +#include "iusace_type_def.h" +#include "iusace_cnst.h" + +#include "iusace_fd_quant.h" +#include "iusace_bitbuffer.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_api.h" +#include "impd_drc_uni_drc_eq.h" +#include "impd_drc_uni_drc_filter_bank.h" +#include "impd_drc_gain_enc.h" +#include "impd_drc_struct_def.h" + +#include "ixheaace_memory_standards.h" +#include "iusace_tns_usac.h" +#include "iusace_psy_mod.h" +#include "iusace_config.h" +#include "iusace_signal_classifier.h" +#include "iusace_fft.h" +#include "iusace_block_switch_const.h" +#include "iusace_block_switch_struct_def.h" +#include "iusace_cnst.h" +#include "iusace_ms.h" +#include "ixheaace_adjust_threshold_data.h" +#include "iusace_fd_qc_util.h" +#include "ixheaace_sbr_header.h" +#include "ixheaace_config.h" +#include "ixheaace_asc_write.h" +#include "iusace_main.h" + +static VOID iusace_calc_pds(FLOAT32 *ptr_input, WORD32 ccfl) { + WORD32 i; + FLOAT64 max_pow, delta; + FLOAT64 log_ccfl_base_10 = (ccfl == 1024) ? LOG_1024_BASE_10 : LOG_768_BASE_10; + + max_pow = MAX( + 10 * (log10(ptr_input[0] * ptr_input[0] + ptr_input[1] * ptr_input[1]) - log_ccfl_base_10) + + 10e-15, + MIN_POW); + + for (i = 1; i < ccfl >> 1; i++) { + /* removed the sqrt along with clubbing the for loops */ + ptr_input[2 * i] = (FLOAT32)MAX(10 * (log10(ptr_input[2 * i] * ptr_input[2 * i] + + ptr_input[2 * i + 1] * ptr_input[2 * i + 1]) - + log_ccfl_base_10) + + 10e-15, + MIN_POW); + + max_pow = MAX(max_pow, ptr_input[2 * i]); + } + + /* Normalized to reference sound pressure level 96 dB */ + delta = 96 - max_pow; + + for (i = 0; i < ccfl >> 1; i++) { + ptr_input[2 * i] = ptr_input[2 * i] + (FLOAT32)delta; + } + return; +} + +static VOID iusace_find_tonal(FLOAT32 *ptr_input, WORD32 *ptr_tonal_flag, FLOAT32 *ptr_scratch, + WORD32 ccfl) { + WORD32 i, j; + WORD32 is_tonal; + FLOAT64 tonal_spl; + FLOAT64 absolute_threshold_xm; + + for (i = 0; i < ccfl >> 1; i++) { + ptr_scratch[i] = ptr_input[2 * i]; + } + + if (ccfl == FRAME_LEN_LONG) { + for (i = 0; i <= 511; i++) { + ptr_tonal_flag[i] = 0; + } + + for (i = 2; i < 500; i++) { + if (ptr_scratch[i] > ptr_scratch[i - 1] && ptr_scratch[i] >= ptr_scratch[i + 1]) { + is_tonal = 1; + + /* Verify it meets the condition: ptr_scratch[i]-ptr_scratch[i+j]>=7 */ + + if (1 < i && i < 62) { + for (j = -2; j <= -2; j++) { + is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7; + if (is_tonal == 0) break; + } + if (is_tonal == 1) { + for (j = 2; j <= 2; j++) { + is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7; + if (is_tonal == 0) break; + } + } + + if (is_tonal == 1) { + ptr_tonal_flag[i] = 1; + } + } + + else if (62 <= i && i < 126) { + for (j = -3; j <= -2; j++) { + is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7; + if (is_tonal == 0) break; + } + if (is_tonal == 1) { + for (j = 2; j <= 3; j++) { + is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7; + if (is_tonal == 0) break; + } + } + + if (is_tonal == 1) { + ptr_tonal_flag[i] = 1; + } + } + + else if (126 <= i && i < 254) { + for (j = -6; j <= -2; j++) { + is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7; + if (is_tonal == 0) break; + } + if (is_tonal == 1) { + for (j = 2; j <= 6; j++) { + is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7; + if (is_tonal == 0) break; + } + } + + if (is_tonal == 1) { + ptr_tonal_flag[i] = 1; + } + } + + else if (254 <= i && i < 500) { + for (j = -12; j <= -2; j++) { + is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7; + if (is_tonal == 0) break; + } + if (is_tonal == 1) { + for (j = 2; j <= 12; j++) { + is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7; + if (is_tonal == 0) break; + } + } + + if (is_tonal == 1) { + ptr_tonal_flag[i] = 1; + } + } + } + } + + for (i = 0; i <= 511; i++) { + if (ptr_tonal_flag[i] == 1) { + /* compute the SPL of tonal */ + tonal_spl = + 10 * log10(pow(10, (ptr_scratch[i - 1] / 10)) + pow(10, (ptr_scratch[i] / 10)) + + pow(10, (ptr_scratch[i + 1] / 10))); + + if (i >= 324) { + absolute_threshold_xm = iusace_classify_arrays.absolute_threshold_1024[i] + 20; + } else { + absolute_threshold_xm = iusace_classify_arrays.absolute_threshold_1024[i]; + } + if (tonal_spl < absolute_threshold_xm) { + ptr_tonal_flag[i] = 0; + } + } + } + } else // (ccfl == 768) + { + for (i = 0; i <= 383; i++) { + ptr_tonal_flag[i] = 0; + } + + for (i = 2; i < 375; i++) { + if (ptr_scratch[i] > ptr_scratch[i - 1] && ptr_scratch[i] >= ptr_scratch[i + 1]) { + is_tonal = 1; + + /* Verify it meets the condition: ptr_scratch[i]-ptr_scratch[i+j]>=7 */ + + if (1 < i && i < 47) { + for (j = -2; j <= -2; j++) { + is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7; + if (is_tonal == 0) break; + } + if (is_tonal == 1) { + for (j = 2; j <= 2; j++) { + is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7; + if (is_tonal == 0) break; + } + } + + if (is_tonal == 1) { + ptr_tonal_flag[i] = 1; + } + } + + else if (47 <= i && i < 95) { + for (j = -3; j <= -2; j++) { + is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7; + if (is_tonal == 0) break; + } + if (is_tonal == 1) { + for (j = 2; j <= 3; j++) { + is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7; + if (is_tonal == 0) break; + } + } + + if (is_tonal == 1) { + ptr_tonal_flag[i] = 1; + } + } + + else if (95 <= i && i < 194) { + for (j = -5; j <= -2; j++) { + is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7; + if (is_tonal == 0) break; + } + if (is_tonal == 1) { + for (j = 2; j <= 5; j++) { + is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7; + if (is_tonal == 0) break; + } + } + + if (is_tonal == 1) { + ptr_tonal_flag[i] = 1; + } + } + + else if (191 <= i && i < 375) { + for (j = -9; j <= -2; j++) { + is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7; + if (is_tonal == 0) break; + } + if (is_tonal == 1) { + for (j = 2; j <= 9; j++) { + is_tonal = is_tonal && ptr_scratch[i] - ptr_scratch[i + j] >= 7; + if (is_tonal == 0) break; + } + } + + if (is_tonal == 1) { + ptr_tonal_flag[i] = 1; + } + } + } + } + + for (i = 0; i <= 383; i++) { + if (ptr_tonal_flag[i] == 1) { + /* compute the SPL of tonal */ + tonal_spl = + 10 * log10(pow(10, (ptr_scratch[i - 1] / 10)) + pow(10, (ptr_scratch[i] / 10)) + + pow(10, (ptr_scratch[i + 1] / 10))); + + if (i >= 243) { + absolute_threshold_xm = iusace_classify_arrays.absolute_threshold_768[i] + 20; + } else { + absolute_threshold_xm = iusace_classify_arrays.absolute_threshold_768[i]; + } + if (tonal_spl < absolute_threshold_xm) { + ptr_tonal_flag[i] = 0; + } + } + } + } + return; +} + +static VOID iusace_tonal_analysis(ia_tonal_params_struct *pstr_ton_params, + iusace_scratch_mem *pstr_scratch, WORD32 ccfl) { + FLOAT32 *ptr_complex_fft = pstr_scratch->p_complex_fft; + WORD32 *ptr_tonal_flag = pstr_scratch->p_tonal_flag; + FLOAT32 *ptr_time_sig = pstr_ton_params->time_signal; + WORD32 framecnt_xm = pstr_ton_params->framecnt_xm; + WORD32 *ptr_n_tonal = pstr_ton_params->n_tonal; + WORD32 *ptr_n_tonal_low_frequency = pstr_ton_params->n_tonal_low_frequency; + FLOAT32 *ptr_n_tonal_low_frequency_ratio = pstr_ton_params->n_tonal_low_frequency_ratio; + FLOAT32 *ave_n_tonal = pstr_ton_params->ave_n_tonal; + FLOAT32 *ave_n_tonal_short = pstr_ton_params->ave_n_tonal_short; + WORD32 i; + WORD32 fft_size = ccfl; + + WORD32 frame_length; + WORD32 n_tonal_total, n_tonal_low_frequency_total; + + for (i = 0; i < ccfl; i++) { + ptr_complex_fft[2 * i] = + (FLOAT32)(ptr_time_sig[i] * ((ccfl == 1024) + ? iusace_classify_arrays.hanning_window_1024[i] + : iusace_classify_arrays.hanning_window_768[i])); + ptr_complex_fft[2 * i + 1] = 0; + } + + iusace_complex_fft(ptr_complex_fft, fft_size, pstr_scratch); + + /* compute power density spectrum */ + /* re_fft contains the resulting pds */ + iusace_calc_pds(ptr_complex_fft, ccfl); + + /* detect tonal */ + iusace_find_tonal(ptr_complex_fft, ptr_tonal_flag, pstr_scratch->p_pow_spec, ccfl); + + /* update n_tonal, n_tonal_low_frequency */ + for (i = 0; i < 99; i++) { + ptr_n_tonal[i] = ptr_n_tonal[i + 1]; + ptr_n_tonal_low_frequency[i] = ptr_n_tonal_low_frequency[i + 1]; + } + ptr_n_tonal[99] = 0; + for (i = 0; i < ccfl >> 1; i++) { + ptr_n_tonal[99] += ptr_tonal_flag[i]; + } + ptr_n_tonal_low_frequency[99] = 0; + for (i = 0; i < INDEXOFLOWFREQUENCY; i++) { + ptr_n_tonal_low_frequency[99] += ptr_tonal_flag[i]; + } + + /* compute long-term AVE and the ratio of distribution in low-frequency domain */ + if (framecnt_xm < AVE_TONAL_LENGTH) { + frame_length = framecnt_xm; + } else { + frame_length = AVE_TONAL_LENGTH; + } + + n_tonal_total = 0; + n_tonal_low_frequency_total = 0; + for (i = 0; i < frame_length; i++) { + n_tonal_total += ptr_n_tonal[99 - i]; + n_tonal_low_frequency_total += ptr_n_tonal_low_frequency[99 - i]; + } + + *ave_n_tonal = (FLOAT32)n_tonal_total / frame_length; + + if (n_tonal_total == 0) { + *ptr_n_tonal_low_frequency_ratio = 1; + } else { + *ptr_n_tonal_low_frequency_ratio = (FLOAT32)n_tonal_low_frequency_total / n_tonal_total; + } + + /* compute the short-term AVE */ + if (framecnt_xm < AVE_TONAL_LENGTH_SHORT) { + frame_length = framecnt_xm; + } else { + frame_length = AVE_TONAL_LENGTH_SHORT; + } + + n_tonal_total = 0; + for (i = 0; i < frame_length; i++) { + n_tonal_total += ptr_n_tonal[99 - i]; + } + + *ave_n_tonal_short = (FLOAT32)n_tonal_total / frame_length; + return; +} + +static VOID iusace_spectral_tilt_analysis(ia_spec_tilt_params_struct *ptr_spec_params, + WORD32 ccfl) { + FLOAT32 *ptr_time_signal = ptr_spec_params->time_signal; + WORD32 framecnt_xm = ptr_spec_params->framecnt_xm; + FLOAT32 *ptr_spec_tilt_buf = ptr_spec_params->spec_tilt_buf; + FLOAT32 *ptr_msd_spec_tilt = ptr_spec_params->msd_spec_tilt; + FLOAT32 *ptr_msd_spec_tilt_short = ptr_spec_params->msd_spec_tilt_short; + WORD32 i; + WORD32 frame_length; + + FLOAT32 r0, r1; + FLOAT32 spec_tilt; + FLOAT32 ave_spec_tilt; + + /* compute spectral tilt */ + r0 = 0; + r1 = 0; + for (i = 0; i < ccfl - 1; i++) { + r0 += ptr_time_signal[i] * ptr_time_signal[i]; + r1 += ptr_time_signal[i] * ptr_time_signal[i + 1]; + } + r0 += ptr_time_signal[i] * ptr_time_signal[i]; + + if (r0 == 0) { + spec_tilt = 1.0f; + } else { + spec_tilt = r1 / r0; + } + + /* update spec_tilt_buf */ + for (i = 0; i < 100 - 1; i++) { + ptr_spec_tilt_buf[i] = ptr_spec_tilt_buf[i + 1]; + } + ptr_spec_tilt_buf[99] = spec_tilt; + + /* compute the long-term mean square deviation of the spectral tilt */ + if (framecnt_xm < SPECTRAL_TILT_LENGTH) { + frame_length = framecnt_xm; + } else { + frame_length = SPECTRAL_TILT_LENGTH; + } + + ave_spec_tilt = 0; + for (i = 0; i < frame_length; i++) { + ave_spec_tilt += ptr_spec_tilt_buf[99 - i]; + } + ave_spec_tilt /= frame_length; + + *ptr_msd_spec_tilt = 0; + for (i = 0; i < frame_length; i++) { + *ptr_msd_spec_tilt += + (ptr_spec_tilt_buf[99 - i] - ave_spec_tilt) * (ptr_spec_tilt_buf[99 - i] - ave_spec_tilt); + } + *ptr_msd_spec_tilt /= frame_length; + + /* compute the short-term mean square deviation of the spectral tilt */ + if (framecnt_xm < SPECTRAL_TILT_LENGTH_SHORT) { + frame_length = framecnt_xm; + } else { + frame_length = SPECTRAL_TILT_LENGTH_SHORT; + } + + ave_spec_tilt = 0; + for (i = 0; i < frame_length; i++) { + ave_spec_tilt += ptr_spec_tilt_buf[99 - i]; + } + ave_spec_tilt /= frame_length; + + *ptr_msd_spec_tilt_short = 0; + for (i = 0; i < frame_length; i++) { + *ptr_msd_spec_tilt_short += + (ptr_spec_tilt_buf[99 - i] - ave_spec_tilt) * (ptr_spec_tilt_buf[99 - i] - ave_spec_tilt); + } + *ptr_msd_spec_tilt_short /= frame_length; + + /* compute the energy of current frame */ + if (r0 <= 1) { + ptr_spec_params->frame_energy = 0; + } else { + ptr_spec_params->frame_energy = (FLOAT32)(10 * log(r0) / log(10)); + } + return; +} + +static WORD32 iusace_init_mode_decision(ia_mode_params_struct *pstr_mode_params) { + WORD32 i; + WORD32 framecnt = pstr_mode_params->framecnt; + WORD32 *framecnt_xm = pstr_mode_params->framecnt_xm; + WORD32 *flag_border = pstr_mode_params->flag_border; + FLOAT32 ave_n_tonal_short = pstr_mode_params->ave_n_tonal_short; + FLOAT32 ave_n_tonal = pstr_mode_params->ave_n_tonal; + FLOAT32 *ave_n_tonal_short_buf = pstr_mode_params->ave_n_tonal_short_buf; + FLOAT32 *ave_n_tonal_buf = pstr_mode_params->ave_n_tonal_buf; + FLOAT32 msd_spec_tilt = pstr_mode_params->msd_spec_tilt; + FLOAT32 msd_spec_tilt_short = pstr_mode_params->msd_spec_tilt_short; + FLOAT32 *msd_spec_tilt_buf = pstr_mode_params->msd_spec_tilt_buf; + FLOAT32 *msd_spec_tilt_short_buf = pstr_mode_params->msd_spec_tilt_short_buf; + FLOAT32 n_tonal_low_frequency_ratio = pstr_mode_params->n_tonal_low_frequency_ratio; + FLOAT32 frame_energy = pstr_mode_params->frame_energy; + WORD32 init_mode_decision_result = TBD; + WORD32 count_msd_st_monchhichi = 0; + WORD32 count_msd_st_speech_music = 0, count_msd_st_music_speech = 0; + WORD32 flag_ave_music_speech = 0; + WORD32 count_msd_st_music = 0; + WORD32 border_state = 0; + WORD32 count_quiet_mode = 0; + + *flag_border = NO_BORDER; + + /* border decision according to spectral tilt */ + + /* update msd_spec_tilt_buf, msd_spec_tilt_short_buf */ + for (i = 0; i < 5 - 1; i++) { + msd_spec_tilt_buf[i] = msd_spec_tilt_buf[i + 1]; + msd_spec_tilt_short_buf[i] = msd_spec_tilt_short_buf[i + 1]; + } + msd_spec_tilt_buf[4] = msd_spec_tilt; + msd_spec_tilt_short_buf[4] = msd_spec_tilt_short; + + /* speech->music find strict border of speech->music */ + if ((msd_spec_tilt >= 0.014) && (msd_spec_tilt_short <= 0.000005)) { + count_msd_st_monchhichi++; + } else { + count_msd_st_monchhichi = 0; + } + if (((*flag_border != BORDER_SPEECH_MUSIC_DEFINITE) && + (*flag_border != BORDER_MUSIC_SPEECH_DEFINITE)) && + (border_state != BORDER_SPEECH_MUSIC_DEFINITE) && (count_msd_st_monchhichi >= 15) && + (*framecnt_xm >= 300)) { + *framecnt_xm = 10; + *flag_border = BORDER_SPEECH_MUSIC; + } + + /* find the relative loose border of speech->music */ + if ((msd_spec_tilt >= 0.0025) && (msd_spec_tilt_short <= 0.000003)) { + count_msd_st_speech_music++; + } else { + count_msd_st_speech_music = 0; + } + if (((*flag_border != BORDER_SPEECH_MUSIC_DEFINITE) && + (*flag_border != BORDER_MUSIC_SPEECH_DEFINITE)) && + (border_state != BORDER_SPEECH_MUSIC_DEFINITE) && (count_msd_st_speech_music >= 15) && + (*framecnt_xm >= 300)) { + *framecnt_xm = 10; + *flag_border = BORDER_SPEECH_MUSIC; + } + + /* music->speech */ + if ((msd_spec_tilt_buf[0] <= 0.0003) && (msd_spec_tilt_short_buf[0] <= 0.0002)) { + count_msd_st_music_speech++; + } + if (((*flag_border != BORDER_SPEECH_MUSIC_DEFINITE) && + (*flag_border != BORDER_MUSIC_SPEECH_DEFINITE)) && + (border_state != BORDER_MUSIC_SPEECH_DEFINITE) && (count_msd_st_music_speech >= 100) && + (msd_spec_tilt >= 0.0008) && (msd_spec_tilt_short >= 0.0025) && (*framecnt_xm >= 20)) { + *framecnt_xm = 10; + *flag_border = BORDER_MUSIC_SPEECH; + } + + /* border decision according to tonal + * update ave_n_tonal_short_buf, ave_n_tonal_buf */ + for (i = 0; i < 5 - 1; i++) { + ave_n_tonal_short_buf[i] = ave_n_tonal_short_buf[i + 1]; + ave_n_tonal_buf[i] = ave_n_tonal_buf[i + 1]; + } + ave_n_tonal_short_buf[4] = ave_n_tonal_short; + ave_n_tonal_buf[4] = ave_n_tonal; + + /* music->speech */ + if ((ave_n_tonal_buf[0] >= 12) && (ave_n_tonal_buf[0] < 15) && + (ave_n_tonal_buf[0] - ave_n_tonal_short_buf[0] >= 5) && (*framecnt_xm >= 20) && + (ave_n_tonal_short - ave_n_tonal_short_buf[0] < 5)) { + *framecnt_xm = 10; + flag_ave_music_speech = 1; + *flag_border = BORDER_MUSIC_SPEECH_DEFINITE; + } + + /* update border decision according to energy */ + if (frame_energy <= 60) { + count_quiet_mode = 0; + } else { + count_quiet_mode++; + } + + if ((*flag_border == BORDER_MUSIC_SPEECH) && (count_quiet_mode <= 5)) { + *flag_border = BORDER_MUSIC_SPEECH_DEFINITE; + *framecnt_xm = 10; + } + + /* MUSIC_DEFINITE and SPEECH_DEFINITE mode decision according to short-term characters */ + + /* ave_n_tonal_short */ + if ((init_mode_decision_result == TBD) && (ave_n_tonal_short >= 19)) { + init_mode_decision_result = MUSIC_DEFINITE; + } + if ((init_mode_decision_result == TBD) && (ave_n_tonal_short <= 1.5)) { + init_mode_decision_result = SPEECH_DEFINITE; + } + + /* msd_spec_tilt_short */ + if (msd_spec_tilt_short >= 0.02) { + init_mode_decision_result = SPEECH_DEFINITE; + } + if ((init_mode_decision_result == TBD) && (msd_spec_tilt_short <= 0.00000025) && + (framecnt >= 10)) { + init_mode_decision_result = MUSIC_DEFINITE; + } + + /* SPEECH mode decision */ + + /* flag_ave_music_speech??ave_n_tonal_short */ + if ((init_mode_decision_result == TBD) && (flag_ave_music_speech == 1)) { + if ((ave_n_tonal_short <= 12) && (*framecnt_xm <= 150)) { + init_mode_decision_result = SPEECH; + } + } + + /* MUSIC_DEFINITE and SPEECH_DEFINITE mode decision */ + + /* ave_n_tonal */ + if ((init_mode_decision_result == TBD) && (ave_n_tonal <= 3)) { + init_mode_decision_result = SPEECH_DEFINITE; + } + if ((init_mode_decision_result == TBD) && (ave_n_tonal >= 15)) { + init_mode_decision_result = MUSIC_DEFINITE; + } + + /** ave_n_tonal_short + */ + if ((init_mode_decision_result == TBD) && (ave_n_tonal_short >= 17)) { + init_mode_decision_result = MUSIC_DEFINITE; + } + + /** msd_spec_tilt + */ + if ((init_mode_decision_result == TBD) && (msd_spec_tilt >= 0.01)) { + init_mode_decision_result = SPEECH_DEFINITE; + } + if ((init_mode_decision_result == TBD) && (framecnt >= 10) && (msd_spec_tilt <= 0.00004)) { + init_mode_decision_result = MUSIC_DEFINITE; + } + + /** n_tonal_low_frequency_ratio + */ + if ((init_mode_decision_result == TBD) && (n_tonal_low_frequency_ratio <= 0.91)) { + init_mode_decision_result = MUSIC_DEFINITE; + } + + /** MUSIC and SPEECH mode decision + */ + + /** msd_spec_tilt + */ + if ((init_mode_decision_result == TBD) && (msd_spec_tilt <= 0.0002) && (*framecnt_xm >= 15)) { + init_mode_decision_result = MUSIC; + } + + /** n_tonal_low_frequency_ratio + */ + if ((init_mode_decision_result == TBD) && (n_tonal_low_frequency_ratio >= 0.95)) { + init_mode_decision_result = SPEECH; + } + if ((init_mode_decision_result == TBD) && (n_tonal_low_frequency_ratio <= 0.935)) { + init_mode_decision_result = MUSIC; + } + + /** the rest of the frame to SPEECH + */ + if (init_mode_decision_result == TBD) { + init_mode_decision_result = SPEECH; + } + + /** MUSIC mode decision according to changes of the MSD of the spectral tilt + */ + + /** compute the changes of the MSD of the spectral tilt + */ + if ((msd_spec_tilt <= 0.007) && (init_mode_decision_result != SPEECH_DEFINITE)) { + if (init_mode_decision_result != SPEECH) { + count_msd_st_music++; + } + } else { + count_msd_st_music = 0; + } + + if ((init_mode_decision_result != SPEECH_DEFINITE) && (count_msd_st_music >= 400) && + (border_state != BORDER_MUSIC_SPEECH_DEFINITE)) { + init_mode_decision_result = MUSIC; + } + + /** update border flag + */ + + if (*flag_border != NO_BORDER) { + border_state = *flag_border; + } + + /** update BORDER_SPEECH_MUSIC_DEFINITE + */ + if (((border_state == BORDER_MUSIC_SPEECH) || (border_state == BORDER_MUSIC_SPEECH_DEFINITE)) && + (init_mode_decision_result == MUSIC_DEFINITE) && (*framecnt_xm >= 20)) { + *flag_border = BORDER_SPEECH_MUSIC_DEFINITE; + *framecnt_xm = 10; + border_state = *flag_border; + } + + /** update BORDER_MUSIC_SPEECH_DEFINITE + */ + if (((border_state == BORDER_SPEECH_MUSIC) || (border_state == BORDER_SPEECH_MUSIC_DEFINITE)) && + (init_mode_decision_result == SPEECH_DEFINITE) && (*framecnt_xm >= 20)) { + *flag_border = BORDER_MUSIC_SPEECH_DEFINITE; + *framecnt_xm = 10; + } + + return init_mode_decision_result; +} + +static WORD32 iusace_smoothing_mode_decision(ia_smooth_params_struct *pstr_smooth_param) { + WORD32 *ptr_init_result_ahead = pstr_smooth_param->init_result_ahead; + WORD32 flag_border = pstr_smooth_param->flag_border; + WORD32 *ptr_flag_border_buf_behind = pstr_smooth_param->flag_border_buf_behind; + WORD32 *ptr_flag_border_buf_ahead = pstr_smooth_param->flag_border_buf_ahead; + FLOAT32 frame_energy = pstr_smooth_param->frame_energy; + FLOAT32 *ptr_frame_energy_buf_behind = pstr_smooth_param->frame_energy_buf_behind; + FLOAT32 *ptr_frame_energy_buf_ahead = pstr_smooth_param->frame_energy_buf_ahead; + WORD32 *ptr_smoothing_result_buf = pstr_smooth_param->smoothing_result_buf; + WORD32 *ptr_init_result_behind = pstr_smooth_param->init_result_behind; + WORD32 init_mode_decision_result = pstr_smooth_param->init_mode_decision_result; + WORD32 i; + + WORD32 mode_decision_result; + + WORD32 num_music, num_speech; + + /** update data array + */ + + /** update init_result_behind, init_result_ahead + */ + for (i = 0; i < 99; i++) { + ptr_init_result_behind[i] = ptr_init_result_behind[i + 1]; + } + ptr_init_result_behind[99] = ptr_init_result_ahead[0]; + + ptr_init_result_ahead[NFRAMEAHEAD - 1] = init_mode_decision_result; + + /** update flag_border_buf_behind, flag_border_buf_ahead + * update frame_energy_buf_behind, frame_energy_buf_ahead + */ + + for (i = 0; i < 9; i++) { + ptr_flag_border_buf_behind[i] = ptr_flag_border_buf_behind[i + 1]; + ptr_frame_energy_buf_behind[i] = ptr_frame_energy_buf_behind[i + 1]; + } + ptr_flag_border_buf_behind[9] = ptr_flag_border_buf_ahead[0]; + ptr_frame_energy_buf_behind[9] = ptr_frame_energy_buf_ahead[0]; + + ptr_flag_border_buf_ahead[NFRAMEAHEAD - 1] = flag_border; + + ptr_frame_energy_buf_ahead[NFRAMEAHEAD - 1] = frame_energy; + + /** smoothing according to past results + */ + + mode_decision_result = ptr_init_result_behind[99]; + + /** update smoothing_result_buf + */ + if (ptr_flag_border_buf_behind[9] == NO_BORDER) { + for (i = 0; i < 99; i++) { + ptr_smoothing_result_buf[i] = ptr_smoothing_result_buf[i + 1]; + } + pstr_smooth_param->num_smoothing++; + } else { + for (i = 0; i < 99; i++) { + ptr_smoothing_result_buf[i] = TBD; + } + pstr_smooth_param->num_smoothing = 1; + } + ptr_smoothing_result_buf[99] = ptr_init_result_behind[99]; + + if (pstr_smooth_param->num_smoothing >= SMOOTHING_LENGTH) { + num_music = 0; + num_speech = 0; + + /** smoothed result count + */ + for (i = 0; i < SMOOTHING_LENGTH; i++) { + if ((ptr_smoothing_result_buf[100 - i] == SPEECH) || + (ptr_smoothing_result_buf[100 - i] == SPEECH_DEFINITE)) { + num_speech++; + } else { + num_music++; + } + } + + /** smoothing + */ + if ((num_speech > num_music) && (init_mode_decision_result != MUSIC_DEFINITE)) { + mode_decision_result = SPEECH; + } + if ((num_music > num_speech) && (init_mode_decision_result != SPEECH_DEFINITE)) { + mode_decision_result = MUSIC; + } + } + + /** correct according to energies and ahead mode decision results + */ + + if ((mode_decision_result == MUSIC) && (ptr_frame_energy_buf_behind[9] <= 60)) { + for (i = 0; i < NFRAMEAHEAD; i++) { + if ((ptr_init_result_ahead[i] == SPEECH_DEFINITE) || (ptr_init_result_ahead[i] == SPEECH)) { + pstr_smooth_param->flag_speech_definite = 1; + } + } + } + if ((pstr_smooth_param->flag_speech_definite == 1) && (mode_decision_result == MUSIC)) { + mode_decision_result = SPEECH; + } else { + pstr_smooth_param->flag_speech_definite = 0; + } + + /** correct MUSIC mode + */ + + if (ptr_frame_energy_buf_behind[9] <= 65) { + pstr_smooth_param->count_small_energy = 0; + } else { + pstr_smooth_param->count_small_energy++; + } + if (((ptr_flag_border_buf_ahead[NFRAMEAHEAD - 1] == BORDER_SPEECH_MUSIC) || + (ptr_flag_border_buf_ahead[NFRAMEAHEAD - 1] == BORDER_SPEECH_MUSIC_DEFINITE)) && + (pstr_smooth_param->count_small_energy <= 30)) { + pstr_smooth_param->flag_music_definite = 1; + } + if ((pstr_smooth_param->flag_music_definite == 1) && + ((mode_decision_result == SPEECH) || (mode_decision_result == SPEECH_DEFINITE))) { + mode_decision_result = MUSIC; + } else { + pstr_smooth_param->flag_music_definite = 0; + } + + return mode_decision_result; +} + +static WORD32 iusace_classification_ccfl(ia_classification_struct *pstr_sig_class, + FLOAT32 *ptr_time_signal, + iusace_scratch_mem *pstr_scratch, WORD32 ccfl) { + WORD32 i; + ia_tonal_params_struct pstr_ton_params; + ia_smooth_params_struct smooth_param; + ia_mode_params_struct pstr_mode_params; + ia_spec_tilt_params_struct ptr_spec_params; + + ia_classification_buf_struct *pstr_buffers = &(pstr_sig_class->buffers); + pFLOAT32 spec_tilt_buf = pstr_sig_class->spec_tilt_buf; + pWORD32 n_tonal = pstr_sig_class->n_tonal; + pWORD32 n_tonal_low_frequency = pstr_sig_class->n_tonal_low_frequency; + pWORD32 framecnt_xm = &(pstr_sig_class->framecnt_xm); + pWORD32 framecnt = &(pstr_sig_class->framecnt); + pFLOAT32 ave_n_tonal_short_buf = pstr_sig_class->ave_n_tonal_short_buf; + pFLOAT32 ave_n_tonal_buf = pstr_sig_class->ave_n_tonal_buf; + pFLOAT32 msd_spec_tilt_buf = pstr_sig_class->msd_spec_tilt_buf; + pFLOAT32 msd_spec_tilt_short_buf = pstr_sig_class->msd_spec_tilt_short_buf; + + FLOAT32 n_tonal_low_frequency_ratio; /* the ratio of distribution of the numbers */ + /* of tonal in the low frequency domain */ + FLOAT32 ave_n_tonal, ave_n_tonal_short; /**< the number of tonal */ + FLOAT32 msd_spec_tilt; /* the long-term MSD of spectral tilt */ + FLOAT32 msd_spec_tilt_short; /* the short-term MSD of spectral tilt */ + + WORD32 init_mode_decision_result; /* the initial mode decision */ + WORD32 flag_border = NO_BORDER; /* flag of current border */ + + WORD32 mode_decision_result; /* final mode decision result */ + + if (pstr_sig_class->init_flag == 0) { + /* initialize */ + pstr_sig_class->init_flag = 1; + + for (i = 0; i < 5; i++) { + n_tonal[i] = 0; + n_tonal_low_frequency[i] = 0; + spec_tilt_buf[i] = 0; + pstr_buffers->init_result_behind[i] = TBD; + pstr_buffers->smoothing_result_buf[i] = TBD; + + ave_n_tonal_short_buf[i] = 0; + ave_n_tonal_buf[i] = 0; + msd_spec_tilt_buf[i] = 0; + msd_spec_tilt_short_buf[i] = 0; + + pstr_buffers->frame_energy_buf_behind[i] = 0; + pstr_buffers->flag_border_buf_behind[i] = NO_BORDER; + } + for (; i < 10; i++) { + n_tonal[i] = 0; + n_tonal_low_frequency[i] = 0; + spec_tilt_buf[i] = 0; + pstr_buffers->init_result_behind[i] = TBD; + pstr_buffers->smoothing_result_buf[i] = TBD; + + pstr_buffers->frame_energy_buf_behind[i] = 0; + pstr_buffers->flag_border_buf_behind[i] = NO_BORDER; + } + + for (; i < 100; i++) { + n_tonal[i] = 0; + n_tonal_low_frequency[i] = 0; + spec_tilt_buf[i] = 0; + pstr_buffers->init_result_behind[i] = TBD; + pstr_buffers->smoothing_result_buf[i] = TBD; + } + for (i = 0; i < NFRAMEAHEAD; i++) { + pstr_buffers->frame_energy_buf_ahead[i] = 0; + pstr_buffers->flag_border_buf_ahead[i] = NO_BORDER; + pstr_buffers->init_result_ahead[i] = TBD; + } + } + + *framecnt += 1; + *framecnt_xm += 1; + + pstr_ton_params.time_signal = (FLOAT32 *)ptr_time_signal; + pstr_ton_params.framecnt_xm = *framecnt_xm; + pstr_ton_params.n_tonal = n_tonal; + pstr_ton_params.n_tonal_low_frequency = n_tonal_low_frequency; + pstr_ton_params.n_tonal_low_frequency_ratio = &n_tonal_low_frequency_ratio; + pstr_ton_params.ave_n_tonal = &ave_n_tonal; + pstr_ton_params.ave_n_tonal_short = &ave_n_tonal_short; + /** analysis tonal + */ + iusace_tonal_analysis(&pstr_ton_params, pstr_scratch, ccfl); + + ptr_spec_params.time_signal = ptr_time_signal; + ptr_spec_params.framecnt_xm = *framecnt_xm; + ptr_spec_params.spec_tilt_buf = spec_tilt_buf; + ptr_spec_params.msd_spec_tilt = &msd_spec_tilt; + ptr_spec_params.msd_spec_tilt_short = &msd_spec_tilt_short; + /** analysis spectral tilt + */ + iusace_spectral_tilt_analysis(&ptr_spec_params, ccfl); + + pstr_mode_params.framecnt = *framecnt; + pstr_mode_params.framecnt_xm = framecnt_xm; + pstr_mode_params.flag_border = &flag_border; + pstr_mode_params.ave_n_tonal_short = ave_n_tonal_short; + pstr_mode_params.ave_n_tonal = ave_n_tonal; + pstr_mode_params.ave_n_tonal_short_buf = ave_n_tonal_short_buf; + pstr_mode_params.ave_n_tonal_buf = ave_n_tonal_buf; + pstr_mode_params.msd_spec_tilt = msd_spec_tilt; + pstr_mode_params.msd_spec_tilt_short = msd_spec_tilt_short; + pstr_mode_params.msd_spec_tilt_buf = msd_spec_tilt_buf; + pstr_mode_params.msd_spec_tilt_short_buf = msd_spec_tilt_short_buf; + pstr_mode_params.n_tonal_low_frequency_ratio = n_tonal_low_frequency_ratio; + pstr_mode_params.frame_energy = ptr_spec_params.frame_energy; + /** initial mode decision and boundary decisions + */ + init_mode_decision_result = iusace_init_mode_decision(&pstr_mode_params); + + smooth_param.flag_border_buf_behind = pstr_buffers->flag_border_buf_behind; + smooth_param.flag_border_buf_ahead = pstr_buffers->flag_border_buf_ahead; + smooth_param.frame_energy = ptr_spec_params.frame_energy; + smooth_param.frame_energy_buf_behind = pstr_buffers->frame_energy_buf_behind; + smooth_param.frame_energy_buf_ahead = pstr_buffers->frame_energy_buf_ahead; + smooth_param.smoothing_result_buf = pstr_buffers->smoothing_result_buf; + smooth_param.init_result_ahead = pstr_buffers->init_result_ahead; + smooth_param.flag_border = flag_border; + smooth_param.init_result_behind = pstr_buffers->init_result_behind; + smooth_param.init_mode_decision_result = init_mode_decision_result; + smooth_param.flag_speech_definite = 0; + smooth_param.count_small_energy = 0; + smooth_param.flag_music_definite = 0; + smooth_param.num_smoothing = 0; + /* smoothing */ + mode_decision_result = iusace_smoothing_mode_decision(&smooth_param); + + return mode_decision_result; +} + +VOID iusace_classification(ia_classification_struct *pstr_sig_class, + iusace_scratch_mem *pstr_scratch, WORD32 ccfl) { + WORD32 n_frames, n_class, avg_cls, nf; + WORD32 i; + FLOAT32 *ptr_time_signal = pstr_scratch->p_time_signal; + WORD32 mode_decision_result; + + n_frames = pstr_sig_class->n_buffer_samples / ccfl; + + for (nf = 0; nf < n_frames; nf++) { + for (i = 0; i < ccfl; i++) { + ptr_time_signal[i] = pstr_sig_class->input_samples[ccfl * nf + i]; + } + + /* classification of ccfl-frame */ + mode_decision_result = + iusace_classification_ccfl(pstr_sig_class, ptr_time_signal, pstr_scratch, ccfl); + + /* coding mode decision of 1024-frame */ + if ((mode_decision_result == MUSIC) || (mode_decision_result == MUSIC_DEFINITE)) { + pstr_sig_class->coding_mode = FD_MODE; + } else if ((mode_decision_result == SPEECH) || (mode_decision_result == SPEECH_DEFINITE)) { + pstr_sig_class->coding_mode = TD_MODE; + } + + pstr_sig_class->class_buf[pstr_sig_class->n_buf_class + nf] = pstr_sig_class->coding_mode; + pstr_sig_class->pre_mode = pstr_sig_class->coding_mode; + } + + /* merge ccfl-frame results */ + pstr_sig_class->n_buf_class += n_frames; + n_class = (pstr_sig_class->n_class_frames > pstr_sig_class->n_buf_class) + ? pstr_sig_class->n_buf_class + : pstr_sig_class->n_class_frames; + { + WORD32 min_cls, max_cls; + + min_cls = max_cls = pstr_sig_class->class_buf[0]; + for (i = 1; i < n_class; i++) { + if (pstr_sig_class->class_buf[i] > max_cls) { + max_cls = pstr_sig_class->class_buf[i]; + } else if (pstr_sig_class->class_buf[i] < min_cls) { + min_cls = pstr_sig_class->class_buf[i]; + } + } + + avg_cls = 0; + for (i = 0; i < n_class; i++) { + if (pstr_sig_class->class_buf[i] == max_cls) { + avg_cls += 1; + } + if (pstr_sig_class->class_buf[i] == min_cls) { + avg_cls += -1; + } + } + + if (avg_cls > 0) { + pstr_sig_class->coding_mode = max_cls; + } else { + pstr_sig_class->coding_mode = min_cls; + } + } + + /* shift, save pre_mode and unused class */ + if (n_class > 0) { + pstr_sig_class->pre_mode = pstr_sig_class->class_buf[n_class - 1]; + } + pstr_sig_class->n_buf_class -= n_class; + pstr_sig_class->n_buffer_samples -= ccfl * n_frames; + + WORD32 minimum = MIN(pstr_sig_class->n_buf_class, pstr_sig_class->n_buffer_samples); + if (minimum == pstr_sig_class->n_buf_class) { + for (i = 0; i < minimum; i++) { + pstr_sig_class->class_buf[i] = pstr_sig_class->class_buf[i + n_class]; + pstr_sig_class->input_samples[i] = pstr_sig_class->input_samples[i + ccfl * n_frames]; + } + + /* shift, save unused samples */ + for (; i < pstr_sig_class->n_buffer_samples; i++) { + pstr_sig_class->input_samples[i] = pstr_sig_class->input_samples[i + ccfl * n_frames]; + } + } else { + for (i = 0; i < minimum; i++) { + pstr_sig_class->class_buf[i] = pstr_sig_class->class_buf[i + n_class]; + pstr_sig_class->input_samples[i] = pstr_sig_class->input_samples[i + ccfl * n_frames]; + } + + /* shift, save unused samples */ + for (; i < pstr_sig_class->n_buf_class; i++) { + pstr_sig_class->class_buf[i] = pstr_sig_class->class_buf[i + n_class]; + } + } +} + +VOID iusace_init_classification(ia_classification_struct *pstr_sig_class) { + pstr_sig_class->pre_mode = FD_MODE; + + pstr_sig_class->n_buffer_samples = 0; + memset(pstr_sig_class->input_samples, 0, 3840 * 2 * sizeof(FLOAT32)); + pstr_sig_class->n_class_frames = 2; + pstr_sig_class->n_buf_class = 0; + + pstr_sig_class->is_switch_mode = 1; + + pstr_sig_class->framecnt = 0; + pstr_sig_class->init_flag = 0; + pstr_sig_class->framecnt_xm = 0; + + memset(&pstr_sig_class->buffers, 0, sizeof(ia_classification_buf_struct)); + memset(pstr_sig_class->spec_tilt_buf, 0, sizeof(FLOAT32) * 100); + memset(pstr_sig_class->n_tonal, 0, sizeof(WORD32) * 100); + memset(pstr_sig_class->n_tonal_low_frequency, 0, sizeof(WORD32) * 100); + memset(pstr_sig_class->msd_spec_tilt_buf, 0, sizeof(FLOAT32) * 5); + memset(pstr_sig_class->msd_spec_tilt_short_buf, 0, sizeof(FLOAT32) * 5); + memset(pstr_sig_class->ave_n_tonal_short_buf, 0, sizeof(FLOAT32) * 5); + memset(pstr_sig_class->ave_n_tonal_buf, 0, sizeof(FLOAT32) * 5); + return; +} diff --git a/encoder/ixheaace_signal_classifier_rom.c b/encoder/ixheaace_signal_classifier_rom.c new file mode 100644 index 0000000..d628127 --- /dev/null +++ b/encoder/ixheaace_signal_classifier_rom.c @@ -0,0 +1,1518 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ +#include "iusace_type_def.h" +#include "iusace_cnst.h" +#include "iusace_signal_classifier.h" + +const ia_signal_classifier_tables iusace_classify_arrays = { + {1.00000000000000000000, 0.99998117528260111000, 0.99992470183914450000, + 0.99983058179582340000, 0.99969881869620425000, 0.99952941750109314000, + 0.99932238458834954000, 0.99907772775264536000, 0.99879545620517241000, + 0.99847558057329477000, 0.99811811290014918000, 0.99772306664419164000, + 0.99729045667869021000, 0.99682029929116567000, 0.99631261218277800000, + 0.99576741446765982000, 0.99518472667219693000, 0.99456457073425542000, + 0.99390697000235606000, 0.99321194923479450000, 0.99247953459870997000, + 0.99170975366909953000, 0.99090263542778001000, 0.99005821026229712000, + 0.98917650996478101000, 0.98825756773074946000, 0.98730141815785843000, + 0.98630809724459867000, 0.98527764238894122000, 0.98421009238692903000, + 0.98310548743121629000, 0.98196386910955524000, 0.98078528040323043000, + 0.97956976568544052000, 0.97831737071962765000, 0.97702814265775439000, + 0.97570213003852857000, 0.97433938278557586000, 0.97293995220556018000, + 0.97150389098625178000, 0.97003125319454397000, 0.96852209427441738000, + 0.96697647104485207000, 0.96539444169768940000, 0.96377606579543984000, + 0.96212140426904158000, 0.96043051941556579000, 0.95870347489587160000, + 0.95694033573220882000, 0.95514116830577078000, 0.95330604035419386000, + 0.95143502096900834000, 0.94952818059303667000, 0.94758559101774109000, + 0.94560732538052128000, 0.94359345816196039000, 0.94154406518302081000, + 0.93945922360218992000, 0.93733901191257496000, 0.93518350993894761000, + 0.93299279883473896000, 0.93076696107898371000, 0.92850608047321559000, + 0.92621024213831138000, 0.92387953251128674000, 0.92151403934204201000, + 0.91911385169005777000, 0.91667905992104270000, 0.91420975570353069000, + 0.91170603200542988000, 0.90916798309052238000, 0.90659570451491533000, + 0.90398929312344334000, 0.90134884704602203000, 0.89867446569395382000, + 0.89596624975618522000, 0.89322430119551532000, 0.89044872324475788000, + 0.88763962040285393000, 0.88479709843093779000, 0.88192126434835505000, + 0.87901222642863353000, 0.87607009419540660000, 0.87309497841829009000, + 0.87008699110871146000, 0.86704624551569265000, 0.86397285612158681000, + 0.86086693863776731000, 0.85772861000027212000, 0.85455798836540053000, + 0.85135519310526520000, 0.84812034480329723000, 0.84485356524970712000, + 0.84155497743689844000, 0.83822470555483808000, 0.83486287498638001000, + 0.83146961230254524000, 0.82804504525775580000, 0.82458930278502529000, + 0.82110251499110465000, 0.81758481315158371000, 0.81403632970594841000, + 0.81045719825259477000, 0.80684755354379933000, 0.80320753148064494000, + 0.79953726910790501000, 0.79583690460888357000, 0.79210657730021239000, + 0.78834642762660634000, 0.78455659715557524000, 0.78073722857209449000, + 0.77688846567323244000, 0.77301045336273699000, 0.76910333764557970000, + 0.76516726562245896000, 0.76120238548426178000, 0.75720884650648457000, + 0.75318679904361252000, 0.74913639452345937000, 0.74505778544146606000, + 0.74095112535495911000, 0.73681656887736990000, 0.73265427167241282000, + 0.72846439044822520000, 0.72424708295146700000, 0.72000250796138165000, + 0.71573082528381859000, 0.71143219574521643000, 0.70710678118654757000, + 0.70275474445722530000, 0.69837624940897292000, 0.69397146088965400000, + 0.68954054473706694000, 0.68508366777270036000, 0.68060099779545313000, + 0.67609270357531603000, 0.67155895484701833000, 0.66699992230363747000, + 0.66241577759017178000, 0.65780669329707864000, 0.65317284295377676000, + 0.64851440102211255000, 0.64383154288979150000, 0.63912444486377573000, + 0.63439328416364549000, 0.62963823891492710000, 0.62485948814238645000, + 0.62005721176328921000, 0.61523159058062682000, 0.61038280627630948000, + 0.60551104140432555000, 0.60061647938386897000, 0.59569930449243347000, + 0.59075970185887428000, 0.58579785745643886000, 0.58081395809576453000, + 0.57580819141784534000, 0.57078074588696737000, 0.56573181078361323000, + 0.56066157619733603000, 0.55557023301960229000, 0.55045797293660481000, + 0.54532498842204646000, 0.54017147272989297000, 0.53499761988709726000, + 0.52980362468629483000, 0.52458968267846884000, 0.51935599016558953000, + 0.51410274419322166000, 0.50883014254310699000, 0.50353838372571758000, + 0.49822766697278187000, 0.49289819222978409000, 0.48755016014843605000, + 0.48218377207912283000, 0.47679923006332225000, 0.47139673682599781000, + 0.46597649576796613000, 0.46053871095824001000, 0.45508358712634384000, + 0.44961132965460660000, 0.44412214457042926000, 0.43861623853852771000, + 0.43309381885315201000, 0.42755509343028220000, 0.42200027079979979000, + 0.41642956009763732000, 0.41084317105790391000, 0.40524131400498986000, + 0.39962419984564679000, 0.39399204006104810000, 0.38834504669882630000, + 0.38268343236508984000, 0.37700741021641831000, 0.37131719395183760000, + 0.36561299780477396000, 0.35989503653498828000, 0.35416352542049051000, + 0.34841868024943451000, 0.34266071731199438000, 0.33688985339222005000, + 0.33110630575987643000, 0.32531029216226298000, 0.31950203081601575000, + 0.31368174039889157000, 0.30784964004153498000, 0.30200594931922820000, + 0.29615088824362396000, 0.29028467725446233000, 0.28440753721127182000, + 0.27851968938505306000, 0.27262135544994898000, 0.26671275747489842000, + 0.26079411791527557000, 0.25486565960451463000, 0.24892760574572026000, + 0.24298017990326398000, 0.23702360599436734000, 0.23105810828067128000, + 0.22508391135979278000, 0.21910124015686977000, 0.21311031991609136000, + 0.20711137619221856000, 0.20110463484209196000, 0.19509032201612833000, + 0.18906866414980628000, 0.18303988795514106000, 0.17700422041214886000, + 0.17096188876030136000, 0.16491312048997009000, 0.15885814333386139000, + 0.15279718525844341000, 0.14673047445536175000, 0.14065823933284924000, + 0.13458070850712622000, 0.12849811079379322000, 0.12241067519921628000, + 0.11631863091190488000, 0.11022220729388318000, 0.10412163387205473000, + 0.09801714032956077000, 0.09190895649713269600, 0.08579731234443988000, + 0.07968243797143012600, 0.07356456359966745400, 0.06744391956366410600, + 0.06132073630220864800, 0.05519524434969003100, 0.04906767432741812600, + 0.04293825693494095900, 0.03680722294135899100, 0.03067480317663658100, + 0.02454122852291226400, 0.01840672990580482000, 0.01227153828571994400, + 0.00613588464915451520, 0.00000000000000006123, 0.00000000000000000000, + -0.00613588464915447530, -0.01227153828571992500, -0.01840672990580482000, + -0.02454122852291228800, -0.03067480317663662600, -0.03680722294135883200, + -0.04293825693494082000, -0.04906767432741801500, -0.05519524434968993400, + -0.06132073630220857800, -0.06744391956366405100, -0.07356456359966742600, + -0.07968243797143012600, -0.08579731234443989400, -0.09190895649713272400, + -0.09801714032956060400, -0.10412163387205459000, -0.11022220729388306000, + -0.11631863091190475000, -0.12241067519921620000, -0.12849811079379317000, + -0.13458070850712617000, -0.14065823933284921000, -0.14673047445536175000, + -0.15279718525844344000, -0.15885814333386145000, -0.16491312048996989000, + -0.17096188876030122000, -0.17700422041214875000, -0.18303988795514095000, + -0.18906866414980619000, -0.19509032201612825000, -0.20110463484209190000, + -0.20711137619221856000, -0.21311031991609136000, -0.21910124015686980000, + -0.22508391135979283000, -0.23105810828067111000, -0.23702360599436720000, + -0.24298017990326387000, -0.24892760574572015000, -0.25486565960451457000, + -0.26079411791527551000, -0.26671275747489837000, -0.27262135544994898000, + -0.27851968938505306000, -0.28440753721127188000, -0.29028467725446233000, + -0.29615088824362379000, -0.30200594931922808000, -0.30784964004153487000, + -0.31368174039889152000, -0.31950203081601569000, -0.32531029216226293000, + -0.33110630575987643000, -0.33688985339222005000, -0.34266071731199438000, + -0.34841868024943456000, -0.35416352542049034000, -0.35989503653498811000, + -0.36561299780477385000, -0.37131719395183754000, -0.37700741021641826000, + -0.38268343236508978000, -0.38834504669882625000, -0.39399204006104810000, + -0.39962419984564679000, -0.40524131400498986000, -0.41084317105790391000, + -0.41642956009763715000, -0.42200027079979968000, -0.42755509343028208000, + -0.43309381885315196000, -0.43861623853852766000, -0.44412214457042920000, + -0.44961132965460654000, -0.45508358712634384000, -0.46053871095824001000, + -0.46597649576796618000, -0.47139673682599764000, -0.47679923006332209000, + -0.48218377207912272000, -0.48755016014843600000, -0.49289819222978404000, + -0.49822766697278187000, -0.50353838372571758000, -0.50883014254310699000, + -0.51410274419322166000, -0.51935599016558964000, -0.52458968267846895000, + -0.52980362468629461000, -0.53499761988709715000, -0.54017147272989285000, + -0.54532498842204646000, -0.55045797293660481000, -0.55557023301960218000, + -0.56066157619733603000, -0.56573181078361312000, -0.57078074588696726000, + -0.57580819141784534000, -0.58081395809576453000, -0.58579785745643886000, + -0.59075970185887416000, -0.59569930449243336000, -0.60061647938386897000, + -0.60551104140432555000, -0.61038280627630948000, -0.61523159058062682000, + -0.62005721176328910000, -0.62485948814238634000, -0.62963823891492698000, + -0.63439328416364549000, -0.63912444486377573000, -0.64383154288979139000, + -0.64851440102211244000, -0.65317284295377676000, -0.65780669329707864000, + -0.66241577759017178000, -0.66699992230363747000, -0.67155895484701833000, + -0.67609270357531592000, -0.68060099779545302000, -0.68508366777270036000, + -0.68954054473706683000, -0.69397146088965400000, -0.69837624940897292000, + -0.70275474445722530000, -0.70710678118654746000, -0.71143219574521643000, + -0.71573082528381859000, -0.72000250796138165000, -0.72424708295146689000, + -0.72846439044822520000, -0.73265427167241282000, -0.73681656887736979000, + -0.74095112535495911000, -0.74505778544146595000, -0.74913639452345926000, + -0.75318679904361241000, -0.75720884650648446000, -0.76120238548426178000, + -0.76516726562245896000, -0.76910333764557959000, -0.77301045336273699000, + -0.77688846567323244000, -0.78073722857209438000, -0.78455659715557524000, + -0.78834642762660623000, -0.79210657730021239000, -0.79583690460888346000, + -0.79953726910790501000, -0.80320753148064483000, -0.80684755354379922000, + -0.81045719825259477000, -0.81403632970594830000, -0.81758481315158371000, + -0.82110251499110465000, -0.82458930278502529000, -0.82804504525775580000, + -0.83146961230254524000, -0.83486287498638001000, -0.83822470555483797000, + -0.84155497743689833000, -0.84485356524970701000, -0.84812034480329712000, + -0.85135519310526520000, -0.85455798836540053000, -0.85772861000027212000, + -0.86086693863776731000, -0.86397285612158670000, -0.86704624551569265000, + -0.87008699110871135000, -0.87309497841829009000, -0.87607009419540660000, + -0.87901222642863341000, -0.88192126434835494000, -0.88479709843093779000, + -0.88763962040285393000, -0.89044872324475788000, -0.89322430119551532000, + -0.89596624975618511000, -0.89867446569395382000, -0.90134884704602203000, + -0.90398929312344334000, -0.90659570451491533000, -0.90916798309052227000, + -0.91170603200542988000, -0.91420975570353069000, -0.91667905992104270000, + -0.91911385169005777000, -0.92151403934204190000, -0.92387953251128674000, + -0.92621024213831127000, -0.92850608047321548000, -0.93076696107898371000, + -0.93299279883473885000, -0.93518350993894750000, -0.93733901191257496000, + -0.93945922360218992000, -0.94154406518302081000, -0.94359345816196039000, + -0.94560732538052128000, -0.94758559101774109000, -0.94952818059303667000, + -0.95143502096900834000, -0.95330604035419375000, -0.95514116830577067000, + -0.95694033573220894000, -0.95870347489587160000, -0.96043051941556579000, + -0.96212140426904158000, -0.96377606579543984000, -0.96539444169768940000, + -0.96697647104485207000, -0.96852209427441727000, -0.97003125319454397000, + -0.97150389098625178000, -0.97293995220556007000, -0.97433938278557586000, + -0.97570213003852857000, -0.97702814265775439000, -0.97831737071962765000, + -0.97956976568544052000, -0.98078528040323043000, -0.98196386910955524000, + -0.98310548743121629000, -0.98421009238692903000, -0.98527764238894122000, + -0.98630809724459867000, -0.98730141815785843000, -0.98825756773074946000, + -0.98917650996478101000, -0.99005821026229712000, -0.99090263542778001000, + -0.99170975366909953000, -0.99247953459870997000, -0.99321194923479450000, + -0.99390697000235606000, -0.99456457073425542000, -0.99518472667219682000, + -0.99576741446765982000, -0.99631261218277800000, -0.99682029929116567000, + -0.99729045667869021000, -0.99772306664419164000, -0.99811811290014918000, + -0.99847558057329477000, -0.99879545620517241000, -0.99907772775264536000, + -0.99932238458834954000, -0.99952941750109314000, -0.99969881869620425000, + -0.99983058179582340000, -0.99992470183914450000, -0.99998117528260111000, + -1.00000000000000000000}, + + { + 0, + 0.000015370317393, + 0.000061480690889, + 0.000138329384457, + 0.000245913504789, + 0.000384229001402, + 0.000553270666797, + 0.00075303213665, + 0.000983505890054, + 0.001244683249805, + 0.00153655438272, + 0.001859108300018, + 0.002212332857725, + 0.002596214757137, + 0.003010739545316, + 0.00345589161564, + 0.003931654208384, + 0.004438009411355, + 0.004974938160566, + 0.005542420240954, + 0.006140434287139, + 0.006768957784229, + 0.007427967068671, + 0.008117437329137, + 0.008837342607462, + 0.009587655799618, + 0.010368348656739, + 0.01117939178618, + 0.012020754652625, + 0.012892405579237, + 0.013794311748852, + 0.014726439205213, + 0.015688752854247, + 0.01668121646539, + 0.017703792672947, + 0.018756442977503, + 0.019839127747368, + 0.020951806220072, + 0.022094436503901, + 0.023266975579469, + 0.024469379301344, + 0.025701602399704, + 0.026963598482046, + 0.028255320034932, + 0.029576718425774, + 0.030927743904671, + 0.032308345606277, + 0.033718471551717, + 0.035158068650547, + 0.03662708270275, + 0.038125458400778, + 0.039653139331631, + 0.041210067978987, + 0.042796185725362, + 0.044411432854319, + 0.046055748552716, + 0.047729070912998, + 0.049431336935522, + 0.051162482530936, + 0.052922442522585, + 0.054711150648972, + 0.056528539566246, + 0.058374540850741, + 0.060249085001554, + 0.062152101443155, + 0.064083518528051, + 0.066043263539481, + 0.068031262694153, + 0.070047441145022, + 0.072091722984109, + 0.074164031245358, + 0.076264287907535, + 0.078392413897163, + 0.080548329091501, + 0.082731952321562, + 0.084943201375164, + 0.08718199300003, + 0.089448242906922, + 0.091741865772811, + 0.094062775244093, + 0.096410883939837, + 0.098786103455079, + 0.101188344364146, + 0.103617516224025, + 0.10607352757777, + 0.108556285957941, + 0.111065697890088, + 0.11360166889627, + 0.116164103498613, + 0.118752905222901, + 0.121367976602213, + 0.12400921918059, + 0.126676533516741, + 0.129369819187789, + 0.132088974793051, + 0.134833897957855, + 0.137604485337396, + 0.140400632620624, + 0.143222234534175, + 0.146069184846332, + 0.148941376371024, + 0.151838700971864, + 0.154761049566218, + 0.157708312129314, + 0.160680377698381, + 0.16367713437683, + 0.166698469338468, + 0.169744268831739, + 0.172814418184015, + 0.175908801805908, + 0.179027303195622, + 0.182169804943345, + 0.18533618873566, + 0.188526335360008, + 0.191740124709171, + 0.194977435785797, + 0.198238146706954, + 0.201522134708718, + 0.204829276150797, + 0.208159446521186, + 0.211512520440851, + 0.214888371668455, + 0.218286873105108, + 0.22170789679915, + 0.225151313950974, + 0.22861699491787, + 0.232104809218908, + 0.235614625539852, + 0.2391463117381, + 0.242699734847664, + 0.246274761084171, + 0.249871255849904, + 0.253489083738869, + 0.25712810854189, + 0.26078819325174, + 0.264469200068298, + 0.268170990403738, + 0.271893424887747, + 0.27563636337277, + 0.279399664939288, + 0.283183187901125, + 0.286986789810779, + 0.290810327464789, + 0.294653656909122, + 0.298516633444598, + 0.302399111632333, + 0.306300945299219, + 0.310221987543421, + 0.314162090739918, + 0.318121106546049, + 0.322098885907107, + 0.326095279061949, + 0.33011013554863, + 0.334143304210072, + 0.338194633199756, + 0.342263969987435, + 0.346351161364878, + 0.35045605345164, + 0.354578491700855, + 0.358718320905051, + 0.362875385202001, + 0.367049528080581, + 0.371240592386673, + 0.375448420329074, + 0.37967285348544, + 0.38391373280825, + 0.388170898630795, + 0.392444190673188, + 0.396733448048399, + 0.401038509268312, + 0.405359212249804, + 0.409695394320852, + 0.41404689222665, + 0.418413542135763, + 0.422795179646288, + 0.427191639792051, + 0.431602757048812, + 0.436028365340499, + 0.440468298045461, + 0.444922388002741, + 0.449390467518371, + 0.453872368371681, + 0.458367921821638, + 0.462876958613196, + 0.467399308983666, + 0.471934802669115, + 0.476483268910768, + 0.481044536461443, + 0.485618433591993, + 0.490204788097777, + 0.494803427305141, + 0.499414178077916, + 0.504036866823943, + 0.508671319501604, + 0.513317361626373, + 0.517974818277392, + 0.522643514104049, + 0.527323273332586, + 0.532013919772712, + 0.53671527682424, + 0.541427167483736, + 0.546149414351177, + 0.550881839636639, + 0.555624265166984, + 0.560376512392572, + 0.565138402393982, + 0.569909755888744, + 0.574690393238098, + 0.579480134453749, + 0.584278799204648, + 0.589086206823778, + 0.59390217631496, + 0.598726526359666, + 0.603559075323841, + 0.60839964126475, + 0.61324804193782, + 0.618104094803507, + 0.622967617034165, + 0.62783842552093, + 0.632716336880616, + 0.637601167462617, + 0.642492733355824, + 0.647390850395544, + 0.652295334170439, + 0.657206000029468, + 0.662122663088837, + 0.667045138238959, + 0.671973240151429, + 0.676906783285994, + 0.681845581897543, + 0.686789450043102, + 0.691738201588827, + 0.69669165021702, + 0.701649609433141, + 0.706611892572826, + 0.711578312808922, + 0.716548683158512, + 0.721522816489962, + 0.726500525529963, + 0.731481622870585, + 0.736465920976327, + 0.741453232191182, + 0.746443368745703, + 0.751436142764068, + 0.756431366271157, + 0.76142885119963, + 0.766428409397002, + 0.771429852632734, + 0.776432992605314, + 0.78143764094935, + 0.786443609242662, + 0.791450709013371, + 0.796458751747002, + 0.801467548893576, + 0.806476911874712, + 0.811486652090724, + 0.816496580927726, + 0.821506509764728, + 0.82651624998074, + 0.831525612961876, + 0.83653441010845, + 0.841542452842081, + 0.84654955261279, + 0.851555520906101, + 0.856560169250138, + 0.861563309222718, + 0.86656475245845, + 0.871564310655822, + 0.876561795584295, + 0.881557019091384, + 0.886549793109749, + 0.89153992966427, + 0.896527240879125, + 0.901511538984867, + 0.906492636325489, + 0.91147034536549, + 0.91644447869694, + 0.92141484904653, + 0.926381269282625, + 0.931343552422311, + 0.936301511638432, + 0.941254960266625, + 0.94620371181235, + 0.951147579957909, + 0.956086378569458, + 0.961019921704023, + 0.965948023616493, + 0.970870498766615, + 0.975787161825984, + 0.980697827685013, + 0.985602311459908, + 0.990500428499628, + 0.995391994392835, + 1.000276824974836, + 1.005154736334522, + 1.010025544821287, + 1.014889067051945, + 1.019745119917632, + 1.024593520590702, + 1.029434086531611, + 1.034266635495786, + 1.039090985540492, + 1.043906955031674, + 1.048714362650804, + 1.053513027401703, + 1.058302768617354, + 1.063083405966708, + 1.06785475946147, + 1.07261664946288, + 1.077368896688468, + 1.082111322218813, + 1.086843747504275, + 1.091565994371717, + 1.096277885031211, + 1.10097924208274, + 1.105669888522866, + 1.110349647751403, + 1.11501834357806, + 1.119675800229079, + 1.124321842353848, + 1.128956295031508, + 1.133578983777536, + 1.138189734550311, + 1.142788373757675, + 1.147374728263459, + 1.151948625394009, + 1.156509892944684, + 1.161058359186337, + 1.165593852871786, + 1.170116203242256, + 1.174625240033814, + 1.179120793483771, + 1.183602694337081, + 1.18807077385271, + 1.192524863809992, + 1.196964796514953, + 1.20139040480664, + 1.205801522063401, + 1.210197982209164, + 1.214579619719689, + 1.218946269628802, + 1.2232977675346, + 1.227633949605648, + 1.23195465258714, + 1.236259713807053, + 1.240548971182264, + 1.244822263224656, + 1.249079429047202, + 1.253320308370012, + 1.257544741526378, + 1.261752569468779, + 1.265943633774871, + 1.270117776653451, + 1.274274840950401, + 1.278414670154597, + 1.282537108403812, + 1.286642000490574, + 1.290729191868017, + 1.294798528655696, + 1.298849857645379, + 1.302883026306822, + 1.306897882793503, + 1.310894275948344, + 1.314872055309404, + 1.318831071115534, + 1.322771174312031, + 1.326692216556233, + 1.330594050223119, + 1.334476528410854, + 1.33833950494633, + 1.342182834390663, + 1.346006372044673, + 1.349809973954327, + 1.353593496916164, + 1.357356798482682, + 1.361099736967705, + 1.364822171451714, + 1.368523961787154, + 1.372204968603712, + 1.375865053313562, + 1.379504078116583, + 1.383121906005548, + 1.386718400771281, + 1.390293427007788, + 1.393846850117352, + 1.3973785363156, + 1.400888352636544, + 1.404376166937582, + 1.407841847904478, + 1.411285265056302, + 1.414706288750344, + 1.418104790186997, + 1.421480641414601, + 1.424833715334266, + 1.428163885704655, + 1.431471027146734, + 1.434755015148498, + 1.438015726069655, + 1.441253037146281, + 1.444466826495444, + 1.447656973119792, + 1.450823356912107, + 1.45396585865983, + 1.457084360049544, + 1.460178743671437, + 1.463248893023713, + 1.466294692516984, + 1.469316027478622, + 1.472312784157071, + 1.475284849726139, + 1.478232112289234, + 1.481154460883588, + 1.484051785484428, + 1.48692397700912, + 1.489770927321276, + 1.492592529234828, + 1.495388676518056, + 1.498159263897597, + 1.500904187062401, + 1.503623342667663, + 1.506316628338712, + 1.508983942674862, + 1.511625185253239, + 1.514240256632551, + 1.516829058356839, + 1.519391492959181, + 1.521927463965364, + 1.524436875897511, + 1.526919634277682, + 1.529375645631426, + 1.531804817491306, + 1.534207058400374, + 1.536582277915615, + 1.53893038661136, + 1.541251296082641, + 1.54354491894853, + 1.545811168855422, + 1.548049960480288, + 1.55026120953389, + 1.552444832763951, + 1.55460074795829, + 1.556728873947918, + 1.558829130610094, + 1.560901438871343, + 1.56294572071043, + 1.5649618991613, + 1.566949898315971, + 1.568909643327401, + 1.570841060412298, + 1.572744076853898, + 1.574618621004711, + 1.576464622289206, + 1.57828201120648, + 1.580070719332867, + 1.581830679324516, + 1.58356182491993, + 1.585264090942454, + 1.586937413302736, + 1.588581729001133, + 1.59019697613009, + 1.591783093876465, + 1.593340022523821, + 1.594867703454674, + 1.596366079152702, + 1.597835093204905, + 1.599274690303735, + 1.600684816249176, + 1.602065417950781, + 1.603416443429678, + 1.60473784182052, + 1.606029563373406, + 1.607291559455748, + 1.608523782554108, + 1.609726186275983, + 1.610898725351551, + 1.612041355635379, + 1.613154034108084, + 1.614236718877949, + 1.615289369182504, + 1.616311945390062, + 1.617304409001205, + 1.618266722650239, + 1.6191988501066, + 1.620100756276215, + 1.620972407202827, + 1.621813770069272, + 1.622624813198712, + 1.623405506055834, + 1.624155819247991, + 1.624875724526315, + 1.625565194786781, + 1.626224204071223, + 1.626852727568314, + 1.627450741614498, + 1.628018223694886, + 1.628555152444097, + 1.629061507647068, + 1.629537270239812, + 1.629982422310136, + 1.630396947098315, + 1.630780828997727, + 1.631134053555434, + 1.631456607472732, + 1.631748478605648, + 1.632009655965398, + 1.632240129718802, + 1.632439891188656, + 1.63260893285405, + 1.632747248350663, + 1.632854832470995, + 1.632931681164564, + 1.632977791538059, + 1.632993161855452, + 1.632977791538059, + 1.632931681164564, + 1.632854832470995, + 1.632747248350663, + 1.63260893285405, + 1.632439891188656, + 1.632240129718802, + 1.632009655965398, + 1.631748478605648, + 1.631456607472732, + 1.631134053555434, + 1.630780828997727, + 1.630396947098315, + 1.629982422310136, + 1.629537270239812, + 1.629061507647068, + 1.628555152444097, + 1.628018223694886, + 1.627450741614498, + 1.626852727568314, + 1.626224204071223, + 1.625565194786781, + 1.624875724526315, + 1.624155819247991, + 1.623405506055834, + 1.622624813198712, + 1.621813770069272, + 1.620972407202827, + 1.620100756276215, + 1.6191988501066, + 1.618266722650239, + 1.617304409001205, + 1.616311945390062, + 1.615289369182504, + 1.614236718877949, + 1.613154034108084, + 1.612041355635379, + 1.610898725351551, + 1.609726186275983, + 1.608523782554108, + 1.607291559455748, + 1.606029563373406, + 1.60473784182052, + 1.603416443429678, + 1.602065417950781, + 1.600684816249176, + 1.599274690303735, + 1.597835093204905, + 1.596366079152702, + 1.594867703454674, + 1.593340022523821, + 1.591783093876465, + 1.59019697613009, + 1.588581729001133, + 1.586937413302736, + 1.585264090942454, + 1.58356182491993, + 1.581830679324516, + 1.580070719332867, + 1.57828201120648, + 1.576464622289206, + 1.574618621004711, + 1.572744076853898, + 1.570841060412298, + 1.568909643327401, + 1.566949898315971, + 1.5649618991613, + 1.56294572071043, + 1.560901438871343, + 1.558829130610094, + 1.556728873947918, + 1.55460074795829, + 1.552444832763951, + 1.55026120953389, + 1.548049960480288, + 1.545811168855422, + 1.54354491894853, + 1.541251296082641, + 1.53893038661136, + 1.536582277915615, + 1.534207058400374, + 1.531804817491306, + 1.529375645631426, + 1.526919634277682, + 1.524436875897511, + 1.521927463965364, + 1.519391492959181, + 1.516829058356839, + 1.514240256632551, + 1.511625185253239, + 1.508983942674862, + 1.506316628338712, + 1.503623342667663, + 1.500904187062401, + 1.498159263897597, + 1.495388676518056, + 1.492592529234828, + 1.489770927321276, + 1.48692397700912, + 1.484051785484428, + 1.481154460883588, + 1.478232112289234, + 1.475284849726139, + 1.472312784157071, + 1.469316027478622, + 1.466294692516984, + 1.463248893023713, + 1.460178743671437, + 1.457084360049544, + 1.45396585865983, + 1.450823356912107, + 1.447656973119792, + 1.444466826495444, + 1.441253037146281, + 1.438015726069655, + 1.434755015148498, + 1.431471027146734, + 1.428163885704655, + 1.424833715334266, + 1.421480641414601, + 1.418104790186997, + 1.414706288750344, + 1.411285265056302, + 1.407841847904478, + 1.404376166937582, + 1.400888352636544, + 1.3973785363156, + 1.393846850117352, + 1.390293427007788, + 1.386718400771281, + 1.383121906005548, + 1.379504078116583, + 1.375865053313562, + 1.372204968603712, + 1.368523961787154, + 1.364822171451714, + 1.361099736967705, + 1.357356798482682, + 1.353593496916164, + 1.349809973954327, + 1.346006372044673, + 1.342182834390663, + 1.33833950494633, + 1.334476528410854, + 1.330594050223119, + 1.326692216556233, + 1.322771174312031, + 1.318831071115534, + 1.314872055309404, + 1.310894275948344, + 1.306897882793503, + 1.302883026306822, + 1.298849857645379, + 1.294798528655696, + 1.290729191868017, + 1.286642000490574, + 1.282537108403812, + 1.278414670154597, + 1.274274840950401, + 1.270117776653451, + 1.265943633774871, + 1.261752569468779, + 1.257544741526378, + 1.253320308370012, + 1.249079429047202, + 1.244822263224656, + 1.240548971182264, + 1.236259713807053, + 1.23195465258714, + 1.227633949605648, + 1.2232977675346, + 1.218946269628802, + 1.214579619719689, + 1.210197982209164, + 1.205801522063401, + 1.20139040480664, + 1.196964796514953, + 1.192524863809992, + 1.18807077385271, + 1.183602694337081, + 1.179120793483771, + 1.174625240033814, + 1.170116203242256, + 1.165593852871786, + 1.161058359186337, + 1.156509892944684, + 1.151948625394009, + 1.147374728263459, + 1.142788373757675, + 1.138189734550311, + 1.133578983777536, + 1.128956295031508, + 1.124321842353848, + 1.119675800229079, + 1.11501834357806, + 1.110349647751403, + 1.105669888522866, + 1.10097924208274, + 1.096277885031211, + 1.091565994371717, + 1.086843747504275, + 1.082111322218813, + 1.077368896688468, + 1.07261664946288, + 1.06785475946147, + 1.063083405966708, + 1.058302768617354, + 1.053513027401703, + 1.048714362650804, + 1.043906955031674, + 1.039090985540492, + 1.034266635495786, + 1.029434086531611, + 1.024593520590702, + 1.019745119917632, + 1.014889067051945, + 1.010025544821287, + 1.005154736334522, + 1.000276824974836, + 0.995391994392835, + 0.990500428499628, + 0.985602311459908, + 0.980697827685013, + 0.975787161825984, + 0.970870498766615, + 0.965948023616493, + 0.961019921704023, + 0.956086378569458, + 0.951147579957909, + 0.94620371181235, + 0.941254960266625, + 0.936301511638432, + 0.931343552422311, + 0.926381269282625, + 0.92141484904653, + 0.91644447869694, + 0.91147034536549, + 0.906492636325489, + 0.901511538984867, + 0.896527240879125, + 0.89153992966427, + 0.886549793109749, + 0.881557019091384, + 0.876561795584295, + 0.871564310655822, + 0.86656475245845, + 0.861563309222718, + 0.856560169250138, + 0.851555520906101, + 0.84654955261279, + 0.841542452842081, + 0.83653441010845, + 0.831525612961876, + 0.82651624998074, + 0.821506509764728, + 0.816496580927726, + 0.811486652090724, + 0.806476911874712, + 0.801467548893576, + 0.796458751747002, + 0.791450709013371, + 0.786443609242662, + 0.78143764094935, + 0.776432992605314, + 0.771429852632734, + 0.766428409397002, + 0.76142885119963, + 0.756431366271157, + 0.751436142764068, + 0.746443368745703, + 0.741453232191182, + 0.736465920976327, + 0.731481622870585, + 0.726500525529963, + 0.721522816489962, + 0.716548683158512, + 0.711578312808922, + 0.706611892572826, + 0.701649609433141, + 0.69669165021702, + 0.691738201588827, + 0.686789450043102, + 0.681845581897543, + 0.676906783285994, + 0.671973240151429, + 0.667045138238959, + 0.662122663088837, + 0.657206000029468, + 0.652295334170439, + 0.647390850395544, + 0.642492733355824, + 0.637601167462617, + 0.632716336880616, + 0.62783842552093, + 0.622967617034165, + 0.618104094803507, + 0.61324804193782, + 0.60839964126475, + 0.603559075323841, + 0.598726526359666, + 0.59390217631496, + 0.589086206823778, + 0.584278799204648, + 0.579480134453749, + 0.574690393238098, + 0.569909755888744, + 0.565138402393982, + 0.560376512392572, + 0.555624265166984, + 0.550881839636639, + 0.546149414351177, + 0.541427167483736, + 0.53671527682424, + 0.532013919772712, + 0.527323273332586, + 0.522643514104049, + 0.517974818277392, + 0.513317361626373, + 0.508671319501604, + 0.504036866823943, + 0.499414178077916, + 0.494803427305141, + 0.490204788097777, + 0.485618433591993, + 0.481044536461443, + 0.476483268910768, + 0.471934802669115, + 0.467399308983666, + 0.462876958613196, + 0.458367921821638, + 0.453872368371681, + 0.449390467518371, + 0.444922388002741, + 0.440468298045461, + 0.436028365340499, + 0.431602757048812, + 0.427191639792051, + 0.422795179646288, + 0.418413542135763, + 0.41404689222665, + 0.409695394320852, + 0.405359212249804, + 0.401038509268312, + 0.396733448048399, + 0.392444190673188, + 0.388170898630795, + 0.38391373280825, + 0.37967285348544, + 0.375448420329074, + 0.371240592386673, + 0.367049528080581, + 0.362875385202001, + 0.358718320905051, + 0.354578491700855, + 0.35045605345164, + 0.346351161364878, + 0.342263969987435, + 0.338194633199756, + 0.334143304210072, + 0.33011013554863, + 0.326095279061949, + 0.322098885907107, + 0.318121106546049, + 0.314162090739918, + 0.310221987543421, + 0.306300945299219, + 0.302399111632333, + 0.298516633444598, + 0.294653656909122, + 0.290810327464789, + 0.286986789810779, + 0.283183187901125, + 0.279399664939288, + 0.27563636337277, + 0.271893424887747, + 0.268170990403738, + 0.264469200068298, + 0.26078819325174, + 0.25712810854189, + 0.253489083738869, + 0.249871255849904, + 0.246274761084171, + 0.242699734847664, + 0.2391463117381, + 0.235614625539852, + 0.232104809218908, + 0.22861699491787, + 0.225151313950974, + 0.22170789679915, + 0.218286873105108, + 0.214888371668455, + 0.211512520440851, + 0.208159446521186, + 0.204829276150797, + 0.201522134708718, + 0.198238146706954, + 0.194977435785797, + 0.191740124709171, + 0.188526335360008, + 0.18533618873566, + 0.182169804943345, + 0.179027303195622, + 0.175908801805908, + 0.172814418184015, + 0.169744268831739, + 0.166698469338468, + 0.16367713437683, + 0.160680377698381, + 0.157708312129314, + 0.154761049566218, + 0.151838700971864, + 0.148941376371024, + 0.146069184846332, + 0.143222234534175, + 0.140400632620624, + 0.137604485337396, + 0.134833897957855, + 0.132088974793051, + 0.129369819187789, + 0.126676533516741, + 0.12400921918059, + 0.121367976602213, + 0.118752905222901, + 0.116164103498613, + 0.11360166889627, + 0.111065697890088, + 0.108556285957941, + 0.10607352757777, + 0.103617516224025, + 0.101188344364146, + 0.098786103455079, + 0.096410883939837, + 0.094062775244093, + 0.091741865772811, + 0.089448242906922, + 0.08718199300003, + 0.084943201375164, + 0.082731952321562, + 0.080548329091501, + 0.078392413897163, + 0.076264287907535, + 0.074164031245358, + 0.072091722984109, + 0.070047441145022, + 0.068031262694153, + 0.066043263539481, + 0.064083518528051, + 0.062152101443155, + 0.060249085001554, + 0.058374540850741, + 0.056528539566246, + 0.054711150648972, + 0.052922442522585, + 0.051162482530936, + 0.049431336935522, + 0.047729070912998, + 0.046055748552716, + 0.044411432854319, + 0.042796185725362, + 0.041210067978987, + 0.039653139331631, + 0.038125458400778, + 0.03662708270275, + 0.035158068650547, + 0.033718471551717, + 0.032308345606277, + 0.030927743904671, + 0.029576718425774, + 0.028255320034932, + 0.026963598482046, + 0.025701602399704, + 0.024469379301344, + 0.023266975579469, + 0.022094436503901, + 0.020951806220072, + 0.019839127747368, + 0.018756442977503, + 0.017703792672947, + 0.01668121646539, + 0.015688752854247, + 0.014726439205213, + 0.013794311748852, + 0.012892405579237, + 0.012020754652625, + 0.01117939178618, + 0.010368348656739, + 0.009587655799618, + 0.008837342607462, + 0.008117437329137, + 0.007427967068671, + 0.006768957784229, + 0.006140434287139, + 0.005542420240954, + 0.004974938160566, + 0.004438009411355, + 0.003931654208384, + 0.00345589161564, + 0.003010739545316, + 0.002596214757137, + 0.002212332857725, + 0.001859108300018, + 0.00153655438272, + 0.001244683249805, + 0.000983505890054, + 0.00075303213665, + 0.000553270666797, + 0.000384229001402, + 0.000245913504789, + 0.000138329384457, + 0.000061480690889, + 0.000015370317393, + }, + + {42.09507, 24.17017, 17.46814, 13.87051, 11.59598, 10.01474, 8.84462, 7.93937, 7.21520, + 6.62048, 6.12152, 5.69534, 5.32567, 5.00063, 4.71133, 4.45091, 4.21402, 3.99635, + 3.79442, 3.60533, 3.42667, 3.25636, 3.09262, 2.93390, 2.77881, 2.62613, 2.47477, + 2.32374, 2.17215, 2.01920, 1.86415, 1.70637, 1.54526, 1.38033, 1.21115, 1.03736, + 0.85867, 0.67489, 0.48590, 0.29165, 0.09220, -0.11230, -0.32164, -0.53548, -0.75341, + -0.97493, -1.19943, -1.42623, -1.65456, -1.88357, -2.11233, -2.33984, -2.56507, -2.78692, + -3.00424, -3.21588, -3.42065, -3.61737, -3.80489, -3.98204, -4.14774, -4.30091, -4.44058, + -4.56582, -4.67582, -4.76986, -4.84730, -4.90767, -4.95058, -4.97579, -4.98318, -4.97278, + -4.94475, -4.89936, -4.83705, -4.75833, -4.66388, -4.55446, -4.43092, -4.29421, -4.14537, + -3.98547, -3.81566, -3.63712, -3.45104, -3.25863, -3.06111, -2.85966, -2.65545, -2.44962, + -2.24324, -2.03734, -1.83289, -1.63077, -1.43181, -1.23673, -1.04621, -0.86080, -0.68101, + -0.50722, -0.33977, -0.17890, -0.02478, 0.12250, 0.26289, 0.39643, 0.52321, 0.64336, + 0.75706, 0.86454, 0.96603, 1.06183, 1.15223, 1.23756, 1.31812, 1.39428, 1.46636, + 1.53471, 1.59966, 1.66154, 1.72068, 1.77738, 1.83195, 1.88466, 1.93580, 1.98561, + 2.03434, 2.08222, 2.12944, 2.17621, 2.22270, 2.26908, 2.31550, 2.36211, 2.40902, + 2.45635, 2.50420, 2.55268, 2.60186, 2.65183, 2.70265, 2.75439, 2.80711, 2.86085, + 2.91567, 2.97161, 3.02871, 3.08700, 3.14652, 3.20730, 3.26937, 3.33276, 3.39749, + 3.46358, 3.53107, 3.59996, 3.67029, 3.74208, 3.81534, 3.89009, 3.96636, 4.04417, + 4.12353, 4.20446, 4.28698, 4.37112, 4.45689, 4.54431, 4.63340, 4.72417, 4.81666, + 4.91087, 5.00683, 5.10455, 5.20407, 5.30538, 5.40852, 5.51351, 5.62037, 5.72911, + 5.83975, 5.95233, 6.06685, 6.18334, 6.30182, 6.42230, 6.54482, 6.66940, 6.79604, + 6.92478, 7.05564, 7.18864, 7.32379, 7.46113, 7.60067, 7.74244, 7.88646, 8.03275, + 8.18133, 8.33223, 8.48547, 8.64107, 8.79906, 8.95945, 9.12228, 9.28756, 9.45532, + 9.62558, 9.79837, 9.97371, 10.15162, 10.33214, 10.51527, 10.70105, 10.88950, 11.08065, + 11.27452, 11.47113, 11.67052, 11.87270, 12.07770, 12.28554, 12.49626, 12.70988, 12.92642, + 13.14591, 13.36837, 13.59383, 13.82232, 14.05386, 14.28849, 14.52622, 14.76708, 15.01110, + 15.25831, 15.50873, 15.76239, 16.01932, 16.27954, 16.54309, 16.80999, 17.08026, 17.35394, + 17.63106, 17.91164, 18.19570, 18.48329, 18.77442, 19.06913, 19.36744, 19.66938, 19.97499, + 20.28428, 20.59730, 20.91406, 21.23460, 21.55896, 21.88714, 22.21920, 22.55515, 22.89503, + 23.23887, 23.58669, 23.93853, 24.29442, 24.65439, 25.01846, 25.38668, 25.75907, 26.13566, + 26.51648, 26.90157, 27.29095, 27.68466, 28.08272, 28.48518, 28.89206, 29.30340, 29.71922, + 30.13956, 30.56445, 30.99392, 31.42801, 31.86674, 32.31016, 32.75829, 33.21117, 33.66883, + 34.13130, 34.59862, 35.07082, 35.54793, 36.02999, 36.51703, 37.00909, 37.50620, 38.00839, + 38.51569, 39.02815, 39.54580, 40.06866, 40.59679, 41.13020, 41.66894, 42.21304, 42.76254, + 43.31746, 43.87786, 44.44376, 45.01519, 45.59220, 46.17482, 46.76309, 47.35704, 47.95670, + 48.56212, 49.17334, 49.79038, 50.41328, 51.04209, 51.67683, 52.31755, 52.96429, 53.61707, + 54.27594, 54.94094, 55.61210, 56.28946, 56.97306, 57.66293, 58.35912, 59.06166, 59.77059, + 60.48596, 61.20779, 61.93613, 62.67101, 63.41248, 64.16057, 64.91533, 65.67678, 66.44498, + 67.21997, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, + 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, + 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, + 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, + 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, + 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, + 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, + 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, + 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, + 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, + 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, + 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, + 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, + 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, + 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, + 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, + 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, + 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, + 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177}, + {0.000000000000000, 0.000030760481167, 0.000112779949177, 0.000246093837901, + 0.000440870080941, 0.000686879055369, 0.000984186926194, 0.001342861544840, + 0.001752711766672, 0.002213834351465, 0.002736191184958, 0.003309635655116, + 0.003934294913484, 0.004620019156850, 0.005356712285051, 0.006144531571996, + 0.006993209965767, 0.007892707778790, 0.008843212071807, 0.009854333151073, + 0.010916093560325, 0.012028709745827, 0.013201664148479, 0.014425047276689, + 0.015699104495563, 0.017033185329530, 0.018417453896375, 0.019852183948482, + 0.021346587217744, 0.022890906984176, 0.024485444791544, 0.026139269880673, + 0.027842710151676, 0.029596094280100, 0.031408344497016, 0.033269878682503, + 0.035181051921246, 0.037150635097889, 0.039169141331374, 0.041236951330620, + 0.043362680481150, 0.045536942295855, 0.047760142261519, 0.050040736297663, + 0.052369443359629, 0.054746692805112, 0.057180777308225, 0.059662526205993, + 0.062192391760441, 0.064778499809810, 0.067411794900194, 0.070092751172746, + 0.072829324229638, 0.075612578539089, 0.078443009038621, 0.081328397885551, + 0.084259934066554, 0.087238132176342, 0.090270597910989, 0.093348649252929, + 0.096472819259661, 0.099650534342827, 0.102873245836709, 0.106141504013211, + 0.109462553370203, 0.112827982826587, 0.116238358567628, 0.119700740742391, + 0.123206859961865, 0.126757296972327, 0.130358925333641, 0.134003621329127, + 0.137691978863859, 0.141430682862859, 0.145211759133023, 0.149035813287609, + 0.152909339765884, 0.156824517618868, 0.160781962670532, 0.164787977218006, + 0.168834897144700, 0.172923346942543, 0.177059435304329, 0.181235658400345, + 0.185452647804085, 0.189716317335448, 0.194019326770942, 0.198362313137268, + 0.202750994305840, 0.207178196842297, 0.211644561557967, 0.216155609492292, + 0.220704337045357, 0.225291387106090, 0.229922083189575, 0.234589594436995, + 0.239294564071224, 0.244042117580538, 0.248825599614235, 0.253645651950733, + 0.258507201737648, 0.263403771758942, 0.268336000537319, 0.273308616753010, + 0.278315323809952, 0.283356755132987, 0.288437440993722, 0.293551267759509, + 0.298698861886265, 0.303884555479440, 0.309102420070826, 0.314353073249471, + 0.319640649378891, 0.324959407213506, 0.330309953552717, 0.335696225622024, + 0.341112671313476, 0.346559884691324, 0.352041606624415, 0.357552475914039, + 0.363093071923179, 0.368666940120481, 0.374268911844568, 0.379899549772578, + 0.385562205101986, 0.391251903193303, 0.396969188036973, 0.402717217858253, + 0.408491213380652, 0.414291697893002, 0.420121638114442, 0.425976451329337, + 0.431856638098140, 0.437764975264213, 0.443697077727661, 0.449653421284210, + 0.455636594692981, 0.461642411382131, 0.467671320338986, 0.473725724187993, + 0.479801635655588, 0.485899474872009, 0.492021460431325, 0.498163804986994, + 0.504326897760746, 0.510512775571917, 0.516717851488916, 0.522942481773147, + 0.529188523872662, 0.535452591618745, 0.541735006262578, 0.548037448428558, + 0.554356732919630, 0.560693143931127, 0.567048187951859, 0.573418880827057, + 0.579805467657200, 0.586209283620153, 0.592627545536981, 0.599060457383266, + 0.605509185983216, 0.611971148931353, 0.618446507059642, 0.624936261924513, + 0.631438031556891, 0.637951931640096, 0.644478801673103, 0.651016459652865, + 0.657564974125067, 0.664125025861768, 0.670694632223683, 0.677273812648260, + 0.683863092627087, 0.690460688151991, 0.697066567602333, 0.703681104747171, + 0.710302713348021, 0.716931308799393, 0.723567116812779, 0.730208747930869, + 0.736856062661974, 0.743509142427464, 0.750166793437365, 0.756828819440175, + 0.763495161432442, 0.770164820054205, 0.776837540450595, 0.783513127151792, + 0.790190773868981, 0.796870165332705, 0.803550973653657, 0.810232584135738, + 0.816914619318297, 0.823596623023038, 0.830278170550667, 0.836958820509605, + 0.843637992641817, 0.850315450533573, 0.856990687161729, 0.863663002471617, + 0.870332346510707, 0.876998144964966, 0.883659582335102, 0.890316793194583, + 0.896969134322659, 0.903615679191336, 0.910256744856389, 0.916891617620176, + 0.923519264400807, 0.930140182586611, 0.936753586480640, 0.943358340975760, + 0.949955121539489, 0.956543069003036, 0.963120950811425, 0.969689618156938, + 0.976248136978331, 0.982795181893834, 0.989331777367596, 0.995856913079257, + 1.002369175479838, 1.008869759756631, 1.015357578019430, 1.021831133245029, + 1.028291788702009, 1.034738377677472, 1.041169324395226, 1.047586157472912, + 1.053987630181872, 1.060372092737283, 1.066741236286030, 1.073093732952280, + 1.079427863704902, 1.085745479315471, 1.092045169693022, 1.098325151335267, + 1.104587431652068, 1.110830517334592, 1.117052565192260, 1.123255736207878, + 1.129438452918968, 1.135598817232102, 1.141739140561731, 1.147857760424573, + 1.153952728607278, 1.160026503741686, 1.166077337526777, 1.172103236404638, + 1.178106802940299, 1.184086202289880, 1.190039400313621, 1.195969140158690, + 1.201873499786520, 1.207750409220584, 1.213602748775361, 1.219428508640527, + 1.225225587725248, 1.230997000035831, 1.236740647489280, 1.242454402575351, + 1.248141409459183, 1.253799481361673, 1.259426469015613, 1.265025643157631, + 1.270594727967834, 1.276131557047198, 1.281639524065326, 1.287116263896822, + 1.292559597593896, 1.297973038072644, 1.303354130718558, 1.308700688571306, + 1.314016340062240, 1.319298540986305, 1.324545100855366, 1.329759759843237, + 1.334939884136100, 1.340083284146627, 1.345193807980001, 1.350268732279556, + 1.355305872726744, 1.360309181511937, 1.365275845886566, 1.370203691103706, + 1.375096769560908, 1.379952179354460, 1.384767759542409, 1.389547658822858, + 1.394288886460288, 1.398989299477233, 1.403653138940366, 1.408277325692910, + 1.412859738803364, 1.417404707752850, 1.421909065461703, 1.426370717043676, + 1.430794076421302, 1.435175889178739, 1.439514090388041, 1.443813174424428, + 1.448069800211358, 1.452281936602054, 1.456454154423200, 1.460583026702180, + 1.464666559802198, 1.468709396990888, 1.472708026253609, 1.476660495094572, + 1.480571515205705, 1.484437490474054, 1.488256513074393, 1.492033359103329, + 1.495764349383079, 1.499447624183555, 1.503088019986575, 1.506681775672865, + 1.510227082923616, 1.513728834589661, 1.517183188823395, 1.520588391921682, + 1.523949389094525, 1.527262259068882, 1.530525305846728, 1.533743522996799, + 1.536912911213060, 1.540031835174002, 1.543105332819083, 1.546129328291029, + 1.549102249795236, 1.552029175669311, 1.554905955075446, 1.557731082472503, + 1.560509672642032, 1.563237501424963, 1.565913132133613, 1.568541712060588, + 1.571118945472871, 1.573643467007091, 1.576120452558198, 1.578545536654044, + 1.580917427594821, 1.583241325996137, 1.585512798568363, 1.587730629480581, + 1.589900040217205, 1.592016531678872, 1.594078965972773, 1.596092581632853, + 1.598052815843059, 1.599958610579751, 1.601815217642407, 1.603618012675739, + 1.605366019316252, 1.607064498882915, 1.608708767742089, 1.610297932839559, + 1.611837261308281, 1.613322012579549, 1.614751378414074, 1.616130628096414, + 1.617454966547338, 1.618723671703162, 1.619942011383258, 1.621105138502488, + 1.622212418387132, 1.623269113822647, 1.624270328301388, 1.625215515606441, + 1.626109929971052, 1.626948628125916, 1.627731153229188, 1.628462747496384, + 1.629138423633379, 1.629757814942189, 1.630326148210112, 1.630838394929557, + 1.631294279164939, 1.631699008922103, 1.632047517364262, 1.632339619785926, + 1.632580502117628, 1.632765062148945, 1.632893206720848, 1.632970096456172, + 1.632990596795965, 1.632954706292398, 1.632867557091704, 1.632723985379264, + 1.632524081431395, 1.632272945814241, 1.631965388616288, 1.631601591699122, + 1.631186621012621, 1.630715263771100, 1.630187793130877, 1.629609237458483, + 1.628974364378760, 1.628283537900820, 1.627541745911614, 1.626743739791113, + 1.625889973808318, 1.624985392546884, 1.624024734544276, 1.623008543586111, + 1.621941718203121, 1.620818987548208, 1.619640984030688, 1.618412557454363, + 1.617128431098838, 1.615789324955430, 1.614400037504079, 1.612955289713351, + 1.611455887967133, 1.609906576902993, 1.608302078789345, 1.606643285066644, + 1.604934884091299, 1.603171603088652, 1.601354417074465, 1.599487955766149, + 1.597566955046745, 1.595592471882273, 1.593569075075383, 1.591491512908748, + 1.589360922531399, 1.587181809638613, 1.584948938693173, 1.582663525119441, + 1.580330009396826, 1.577943175984615, 1.575504316536255, 1.573017804291826, + 1.570478447556724, 1.567887612030697, 1.565249601776904, 1.562559252826900, + 1.559818002609595, 1.557030084160225, 1.554190365144244, 1.551300352270490, + 1.548364205782560, 1.545376828912380, 1.542339795069843, 1.539257190031045, + 1.536123956548920, 1.532941732028453, 1.529714526190757, 1.526437325283359, + 1.523111827875973, 1.519741966136046, 1.516322773795375, 1.512856007636461, + 1.509345520863557, 1.505786398695520, 1.502180453057048, 1.498531456869096, + 1.494834550850454, 1.491091598881856, 1.487306292370465, 1.483473831554925, + 1.479596128973431, 1.475676793378598, 1.471711088552793, 1.467700972284005, + 1.463649969619307, 1.459553411909516, 1.455413298679046, 1.451233070308160, + 1.447008129738569, 1.442740514615581, 1.438433579780980, 1.434082803784382, + 1.429690258677922, 1.425259212982634, 1.420785224864456, 1.416270396973471, + 1.411717910816826, 1.407123408173400, 1.402489018391388, 1.397817835359682, + 1.393105588451732, 1.388354429726971, 1.383567364940026, 1.378740215022338, + 1.373875150674699, 1.368975089089314, 1.364035946697595, 1.359059908692946, + 1.354049803364256, 1.349001646560229, 1.343917633743460, 1.338800504045259, + 1.333646376621038, 1.328457452908788, 1.323236382713885, 1.317979392356718, + 1.312688684890882, 1.307366820712585, 1.302010137131073, 1.296620834394211, + 1.291201383490055, 1.285748236502974, 1.280263586396748, 1.274749814835628, + 1.269203492424505, 1.263626800312312, 1.258022031006155, 1.252385877332783, + 1.246720504047747, 1.241028114748947, 1.235305528139015, 1.229554887958567, + 1.223778309224351, 1.217972740118426, 1.212140298706659, 1.206283011831647, + 1.200397960704723, 1.194487233023788, 1.188552767941960, 1.182591783192853, + 1.176606331384643, 1.170598264542006, 1.164564940353835, 1.158508371593233, + 1.152430323792451, 1.146328297965529, 1.140204262286522, 1.134059896504814, + 1.127892848263231, 1.121705036359193, 1.115498055540812, 1.109269703314048, + 1.103021844313512, 1.096755989138146, 1.090470088319039, 1.084165947538316, + 1.077844994166743, 1.071505334847167, 1.065148711521155, 1.058776469319507, + 1.052386874005143, 1.045981598997687, 1.039561908241716, 1.033126229547265, + 1.026676163042462, 1.020212892603169, 1.013735010929416, 1.007244040105246, + 1.000741085117283, 0.994224906311405, 0.987696942997102, 0.981158222511339, + 0.974607675511872, 0.968046653830431, 0.961476108452113, 0.954895142919997, + 0.948305016917242, 0.941706606431163, 0.935099190368291, 0.928483931629950, + 0.921861632614053, 0.915231749970759, 0.908595345228958, 0.901953148657829, + 0.895304796930764, 0.888651245661392, 0.881993154501071, 0.875330342322911, + 0.868663654335313, 0.861993681130877, 0.855320425853310, 0.848644618873746, + 0.841966783331124, 0.835287108602589, 0.828606205852922, 0.821924532416390, + 0.815242465756012, 0.808560493529090, 0.801879008955912, 0.795198579325110, + 0.788519564558288, 0.781842295491965, 0.775167530865183, 0.768495498713465, + 0.761826469257048, 0.755161394193083, 0.748500365603334, 0.741843594894274, + 0.735192228109670, 0.728546217397363, 0.721905717185347, 0.715272069131303, + 0.708645081561267, 0.702024853790510, 0.695412924234775, 0.688808953607394, + 0.682212988004840, 0.675626763620051, 0.669049789864370, 0.662482061535261, + 0.655925513495171, 0.649379500270371, 0.642843967302610, 0.636321048887673, + 0.629809941194336, 0.623310542273129, 0.616825186486859, 0.610352908289494, + 0.603893560323669, 0.597449677521237, 0.591020129383471, 0.584604725144928, + 0.578206200675401, 0.571823257409281, 0.565455663186984, 0.559106355050661, + 0.552773863381470, 0.546457916651403, 0.540161653173624, 0.533883429421625, + 0.527622936534106, 0.521383514056959, 0.515163341837468, 0.508962075723232, + 0.502783256316546, 0.496624884259705, 0.490486582156116, 0.484372091349118, + 0.478279230840760, 0.472207592039540, 0.466161116574541, 0.460137439519498, + 0.454136123137324, 0.448161308746796, 0.442210445356001, 0.436283068129311, + 0.430383517337686, 0.424509053940399, 0.418659188045740, 0.412838457997269, + 0.407043934879755, 0.401275105780988, 0.395536706094950, 0.389825615366898, + 0.384141299690550, 0.378488690345129, 0.372864473835109, 0.367268097275162, + 0.361704686521243, 0.356170733702469, 0.350665668955837, 0.345194811262003, + 0.339754457209635, 0.334344021943590, 0.328969015973537, 0.323625539354784, + 0.318312994207534, 0.313037080831140, 0.307793701929345, 0.302582248544990, + 0.297408608884227, 0.292268487658141, 0.287161266757181, 0.282093020268053, + 0.277059254447464, 0.272059343934019, 0.267099546525684, 0.262175169744550, + 0.257285582851440, 0.252437225043642, 0.247625205011852, 0.242848888484650, + 0.238114893604583, 0.233418130319444, 0.228757962640598, 0.224141185060282, + 0.219562509058819, 0.215021298712913, 0.210524522128147, 0.206066692781255, + 0.201647176562460, 0.197273112314382, 0.192938816163880, 0.188643657526601, + 0.184394942966888, 0.180186792106451, 0.176018579560174, 0.171897776460845, + 0.167818306961809, 0.163779552511123, 0.159789145519912, 0.155840815902893, + 0.151933953533610, 0.148076348675843, 0.144261538429095, 0.140488922641387, + 0.136766445869269, 0.133087454014668, 0.129451358404114, 0.125866254194286, + 0.122325297901807, 0.118827913789192, 0.115382343789424, 0.111981557040952, + 0.108624992151650, 0.105321033877470, 0.102062466180739, 0.098848743374481, + 0.095688388956531, 0.092574004109972, 0.089505060161748, 0.086490215144628, + 0.083521890053879, 0.080599574486731, 0.077732056680043, 0.074911580226811, + 0.072137654197201, 0.069419192579497, 0.066748264543485, 0.064124399779919, + 0.061556633456213, 0.059036863490728, 0.056564641286282, 0.054149118499742, + 0.051782025161634, 0.049462935420966, 0.047201112619402, 0.044988122453887, + 0.042823562795344, 0.040716803753032, 0.038659250433984, 0.036650525347308, + 0.034700100342705, 0.032799223868901, 0.030947543929075, 0.029154628978895, + 0.027411574926724, 0.025718056064402, 0.024083732214537, 0.022499551047611, + 0.020965213876597, 0.019490466550293, 0.018066112986380, 0.016691882188546, + 0.015377600592239, 0.014113933027891, 0.012900636795909, 0.011747613383075, + 0.010645393376313, 0.009593762914537, 0.008602692907878, 0.007662584719234, + 0.006773253803032, 0.005944734775284, 0.005167304967477, 0.004440809561286, + 0.003775341074914, 0.003161058171410, 0.002597836105722, 0.002095819411702, + 0.001645053614353, 0.001245444321860, 0.000907182117740, 0.000620205083684, + 0.000384449394708, 0.000210145642097, 0.000087130320033, 0.000015370317393}, + { + 42.09507, 5.67600, 2.81141, 0.85388, -1.65843, -4.05209, -4.93974, -3.39411, -1.07381, + 0.76315, 1.70560, 2.31972, 2.92139, 3.69103, 4.65802, 5.85391, 7.36113, 9.16553, + 11.30384, 13.88497, 16.88144, 20.33828, 24.39416, 29.00439, 34.22288, 40.22076, 46.93258, + 54.42187, 62.89473, 67.76090, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, + 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 66.39957, 17.47850, 4.34770, + 2.11351, -0.02492, -2.62621, -4.68516, -4.49191, -2.55273, -0.28631, 1.14285, 1.94363, + 2.52617, 3.18488, 4.01282, 5.05373, 6.37579, 7.97225, 9.88572, 12.20427, 14.91077, + 18.05890, 21.76027, 25.98414, 30.79618, 36.33342, 42.54831, 49.51970, 57.41168, 66.15693, + 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, + 68.00177, 68.00177, 68.00177, 68.00177, 47.41888, 8.73844, 3.32010, 1.39067, -0.93696, + -3.52633, -4.79758, -3.94102, -1.69902, 0.29641, 1.48721, 2.16480, 2.75154, 3.45827, + 4.35742, 5.50907, 6.91332, 8.61759, 10.69142, 13.12681, 15.98476, 19.35260, 23.21203, + 27.63901, 32.73964, 38.48255, 44.96027, 52.29843, 60.45007, 68.00177, 68.00177, 68.00177, + 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, + 68.00177, 68.00177, 25.88398, 5.09335, 2.63477, 0.63653, -1.88005, -4.16971, -4.77761, + -3.23717, -0.90535, 0.82919, 1.77539, 2.36959, 2.98440, 3.75629, 4.75171, 5.97879, + 7.48888, 9.33521, 11.51770, 14.10340, 17.15802, 20.67428, 24.73701, 29.42439, 34.71964, + 40.72734, 47.53806, 55.12343, 63.39477, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, + 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, + 10.61443, 4.07901, 1.95973, -0.20700, -2.81664, -4.70900, -4.44741, -2.36668, -0.15346, + 1.25016, 1.99597, 2.57676, 3.24137, 4.09482, 5.15917, 6.48949, 8.12486, 10.07196, + 12.40276, 15.16379, 18.35752, 22.07621, 26.37303, 31.24430, 36.80503, 43.11406, 50.15986, + 58.08273, 65.73708, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, + 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 57.25222, 7.25918, 3.19379, + 1.23366, -1.15670, -3.71354, -4.87508, -3.77074, -1.49395, 0.45121, 1.55105, 2.20859, + 2.80147, 3.52958, 4.44534, 5.60969, 7.04994, 8.77852, 10.87117, 13.35762, 16.24876, + 19.64303, 23.57135, 28.04166, 33.17790, 39.01031, 45.54260, 52.92719, 61.19167, 67.53040, + 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, + 68.00177, 68.00177, 68.00177, 68.00177, 35.10236, 4.93273, 2.46479, 0.42936, -2.12379, + -4.33583, -4.66992, -3.02376, -0.71474, 0.91623, 1.82697, 2.41749, 3.04617, 3.82850, + 4.84021, 6.10052, 7.62674, 9.49739, 11.72755, 14.33541, 17.42431, 21.00553, 25.09722, + 29.83086, 35.21110, 41.25527, 48.12633, 55.81945, 64.35043, 68.00177, 68.00177, 68.00177, + 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, + 68.00177, 68.00177, 12.33035, 3.79943, 1.78379, -0.41235, -3.02282, -4.70885, -4.34098, + -2.17750, -0.02967, 1.33742, 2.05045, 2.63050, 3.29982, 4.17214, 5.26704, 6.60640, + 8.27057, 10.26211, 12.60532, 15.40728, 18.66212, 22.39692, 26.74926, 31.70112, 37.28192, + 43.66357, 50.81216, 58.75918, 66.33846, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, + 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, + 6.25711, 3.03493, 1.08615, -1.36399, -3.83611, -4.95611, -3.63177, -1.32288, 0.60532, + 1.62498, 2.25646, 2.84905, 3.59673, 4.54034, 5.70767, 7.18029, 8.95018, 11.04670, + 13.57958, 16.52813, 19.92709, 23.91883, 28.46544, 33.60696, 39.52277, 46.15298, 53.54317, + 61.91406, 67.46523, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, + 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, 68.00177, + }}; diff --git a/encoder/ixheaace_static_bits.c b/encoder/ixheaace_static_bits.c index 99b7916..9d23afd 100644 --- a/encoder/ixheaace_static_bits.c +++ b/encoder/ixheaace_static_bits.c @@ -21,6 +21,10 @@ #include #include "ixheaac_type_def.h" #include "ixheaace_aac_constants.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" #include "ixheaace_api.h" #include "ixheaace_adjust_threshold_data.h" #include "ixheaace_psy_const.h" diff --git a/encoder/ixheaace_struct_def.h b/encoder/ixheaace_struct_def.h index 83d5d47..d1b921a 100644 --- a/encoder/ixheaace_struct_def.h +++ b/encoder/ixheaace_struct_def.h @@ -54,8 +54,10 @@ typedef struct { WORD32 mps_tree_config; WORD32 use_mps; WORD32 eldsbr_found; + WORD32 ccfl_idx; UWORD32 ui_pcm_wd_sz; WORD32 frame_length; + ia_usac_encoder_config_struct usac_config; } ixheaace_config_struct; typedef struct ixheaace_state_struct { @@ -86,6 +88,9 @@ typedef struct ixheaace_state_struct { ixheaace_iir21_resampler down_sampler[MAXIMUM_BS_ELE][IXHEAACE_MAX_CH_IN_BS_ELE]; ixheaace_iir_sos_resampler down_samp_sos[MAXIMUM_BS_ELE][IXHEAACE_MAX_CH_IN_BS_ELE]; ixheaace_iir_sos_resampler up_sampler[MAXIMUM_BS_ELE][IXHEAACE_MAX_CH_IN_BS_ELE]; + ixheaace_iir21_resampler hbe_down_sampler[MAXIMUM_BS_ELE][IXHEAACE_MAX_CH_IN_BS_ELE]; + ixheaace_iir_sos_resampler hbe_down_samp_sos[MAXIMUM_BS_ELE][IXHEAACE_MAX_CH_IN_BS_ELE]; + ixheaace_iir_sos_resampler hbe_up_sampler[MAXIMUM_BS_ELE][IXHEAACE_MAX_CH_IN_BS_ELE]; UWORD8 num_anc_data_bytes[MAXIMUM_BS_ELE][IXHEAACE_MAX_CH_IN_BS_ELE]; UWORD8 anc_data_bytes[MAXIMUM_BS_ELE][IXHEAACE_MAX_PAYLOAD_SIZE]; WORD32 total_fill_bits; @@ -95,6 +100,7 @@ typedef struct ixheaace_state_struct { FLOAT32 **pp_drc_in_buf; FLOAT32 *mps_scratch; ixheaace_audio_specific_config_struct audio_specific_config; + ia_usac_data_struct str_usac_enc_data; ia_bit_buf_struct str_bit_buf; ixheaace_mps_212_memory_struct *mps_pers_mem; ixheaace_mps_515_memory_struct *mps_515_pers_mem; @@ -112,6 +118,7 @@ typedef struct ixheaace_api_struct { ixheaace_aac_tables pstr_aac_tabs; ixheaace_comm_tables common_tabs; ixheaace_str_sbr_tabs spectral_band_replication_tabs; + WORD32 usac_en; VOID *pstr_mps_212_enc; VOID *pstr_mps_515_enc; } ixheaace_api_struct; diff --git a/encoder/ixheaace_tns.c b/encoder/ixheaace_tns.c index beb5975..2babda6 100644 --- a/encoder/ixheaace_tns.c +++ b/encoder/ixheaace_tns.c @@ -238,8 +238,6 @@ static WORD32 ia_enhaacplus_enc_index_search3( WORD32 index = 0; WORD32 i; - /* tns_coeff_3_borders[] */ - for (i = 0; i < 8; i++) { if (parcor > pstr_tns_tab->tns_coeff_3_borders[i]) { index = i; @@ -252,8 +250,6 @@ static WORD32 ia_enhaacplus_enc_index_search4( FLOAT32 parcor, ixheaace_temporal_noise_shaping_tables *pstr_tns_tab) { WORD32 index = 0; WORD32 i; - - /* tns_coeff_4_borders[] */ for (i = 0; i < 16; i++) { if (parcor > pstr_tns_tab->tns_coeff_4_borders[i]) { index = i; diff --git a/encoder/ixheaace_tns_hp.c b/encoder/ixheaace_tns_hp.c index cbf0110..c3ef7cd 100644 --- a/encoder/ixheaace_tns_hp.c +++ b/encoder/ixheaace_tns_hp.c @@ -22,6 +22,10 @@ #include #include "ixheaac_type_def.h" #include "ixheaac_constants.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" #include "ixheaace_api.h" #include "ixheaace_aac_constants.h" #include "ixheaace_common_rom.h" @@ -123,8 +127,9 @@ VOID ia_enhaacplus_enc_calc_weighted_spectrum(FLOAT32 *ptr_spectrum, FLOAT32 *pt } } - ptr_weighted_spec[lpc_start_line + 1] = (FLOAT32)( - ((ptr_weighted_spec[lpc_start_line + 1]) + (ptr_weighted_spec[lpc_start_line])) * 0.5f); + ptr_weighted_spec[lpc_start_line + 1] = (FLOAT32)(((ptr_weighted_spec[lpc_start_line + 1]) + + (ptr_weighted_spec[lpc_start_line])) * + 0.5f); multout_temp = (ptr_weighted_spec[lpc_start_line] * ptr_spectrum[lpc_start_line]); ptr_weighted_spec[lpc_start_line] = multout_temp; diff --git a/encoder/ixheaace_tns_params.c b/encoder/ixheaace_tns_params.c index 3aa1090..3a165fa 100644 --- a/encoder/ixheaace_tns_params.c +++ b/encoder/ixheaace_tns_params.c @@ -23,6 +23,10 @@ #include #include "ixheaac_type_def.h" #include "ixheaac_constants.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" #include "ixheaace_api.h" #include "ixheaace_aac_constants.h" #include "ixheaace_psy_const.h" diff --git a/encoder/ixheaace_write_adts_adif.c b/encoder/ixheaace_write_adts_adif.c index 48a7fe4..e7f080d 100644 --- a/encoder/ixheaace_write_adts_adif.c +++ b/encoder/ixheaace_write_adts_adif.c @@ -103,9 +103,7 @@ static WORD32 ia_enhaacplus_enc_putbit(ixheaace_bitstream_params *pstr_bitstream return 0; } -static WORD16 ia_enhaacplus_enc_get_sample_rate_index( - WORD32 sample_rate) /* in : : sampling frequency information */ -{ +static WORD16 ia_enhaacplus_enc_get_sample_rate_index(WORD32 sample_rate) { if (92017 <= sample_rate) { return 0; } @@ -245,7 +243,6 @@ WORD32 ia_enhaacplus_enc_write_pce(WORD32 samp_rate, WORD32 ch_mask, WORD32 num_ } } - /* loop for numSideChannel elements */ for (i = 0; i < num_side_chan_ele; i++) { if ((ch_mask & 0xC0) == 0xC0) { /* stereo channel */ @@ -259,7 +256,6 @@ WORD32 ia_enhaacplus_enc_write_pce(WORD32 samp_rate, WORD32 ch_mask, WORD32 num_ ixheaace_write_bits(pstr_bit_stream_handle, 0x02, 4); } - /* loop for numBackChannel elements */ for (i = 0; i < num_back_chan_ele; i++) { if ((ch_mask & 0x30) == 0x30) { /* stereo channel */ @@ -273,7 +269,6 @@ WORD32 ia_enhaacplus_enc_write_pce(WORD32 samp_rate, WORD32 ch_mask, WORD32 num_ ixheaace_write_bits(pstr_bit_stream_handle, 0x01, 4); } - /* loop for numLFEChannel elements */ for (i = 0; i < num_lfe_chan_ele; i++) { /* element tag select */ ixheaace_write_bits(pstr_bit_stream_handle, 0x00, 4); diff --git a/encoder/ixheaace_write_bitstream.c b/encoder/ixheaace_write_bitstream.c index 3506e14..5b33976 100644 --- a/encoder/ixheaace_write_bitstream.c +++ b/encoder/ixheaace_write_bitstream.c @@ -22,6 +22,10 @@ #include #include "ixheaac_type_def.h" #include "ixheaac_constants.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" #include "ixheaace_api.h" #include "ixheaace_aac_constants.h" #include "ixheaac_error_standards.h" @@ -254,21 +258,21 @@ static VOID ia_enhaacplus_enc_encode_ms_info(WORD32 sfb_cnt, WORD32 sfb_grp, WOR num_of_bits = (UWORD8)max_sfb; for (sfb_offset = 0; sfb_offset < sfb_cnt; sfb_offset += sfb_grp) { - WORD8 Flag; + WORD8 flag; jsflag = &js_flags[sfb_offset]; tmp_var = 0; for (sfb = num_of_bits - 1; sfb >= 0; sfb--) { - Flag = (WORD8)(*jsflag++); - tmp_var = ((tmp_var << 1) | Flag); + flag = (WORD8)(*jsflag++); + tmp_var = ((tmp_var << 1) | flag); } ixheaace_write_bits(pstr_bit_stream_handle, tmp_var, num_of_bits); if (remaining) { for (sfb = remaining - 1; sfb >= 0; sfb--) { - Flag = (WORD8)(*jsflag++); - tmp_var = ((tmp_var << 1) | Flag); + flag = (WORD8)(*jsflag++); + tmp_var = ((tmp_var << 1) | flag); } ixheaace_write_bits(pstr_bit_stream_handle, tmp_var, remaining); @@ -452,7 +456,7 @@ static IA_ERRORCODE ia_enhaacplus_enc_write_single_chan_elem( } static IA_ERRORCODE ia_enhaacplus_enc_write_channel_pair_element( - WORD32 instance_tag, WORD32 ms_digest, WORD32 msFlags[MAXIMUM_GROUPED_SCALE_FACTOR_BAND], + WORD32 instance_tag, WORD32 ms_digest, WORD32 ms_flags[MAXIMUM_GROUPED_SCALE_FACTOR_BAND], WORD32 *pstr_sfb_offset[2], ixheaace_qc_out_channel pstr_qc_out_ch[2], ixheaace_bit_buf_handle pstr_bit_stream_handle, WORD32 aot, ixheaace_temporal_noise_shaping_params pstr_tns_info[2], @@ -482,9 +486,10 @@ static IA_ERRORCODE ia_enhaacplus_enc_write_channel_pair_element( &(pstr_qc_out_ch[0].section_data), pstr_bit_stream_handle, aot); - ia_enhaacplus_enc_encode_ms_info( - pstr_qc_out_ch[0].section_data.sfb_cnt, pstr_qc_out_ch[0].section_data.sfb_per_group, - pstr_qc_out_ch[0].section_data.max_sfb_per_grp, ms_digest, msFlags, pstr_bit_stream_handle); + ia_enhaacplus_enc_encode_ms_info(pstr_qc_out_ch[0].section_data.sfb_cnt, + pstr_qc_out_ch[0].section_data.sfb_per_group, + pstr_qc_out_ch[0].section_data.max_sfb_per_grp, ms_digest, + ms_flags, pstr_bit_stream_handle); err_code = ia_enhaacplus_enc_write_ic_stream( 1, pstr_qc_out_ch[0].win_shape, pstr_qc_out_ch[0].grouping_mask, pstr_sfb_offset[0], pstr_qc_out_ch[0].scalefactor, pstr_qc_out_ch[0].max_val_in_sfb, @@ -742,7 +747,7 @@ IA_ERRORCODE ia_enhaacplus_enc_write_bitstream( case ID_CPE: /* channel pair */ { WORD32 ms_digest = pstr_psy_out->psy_out_element.tools_info.ms_digest; - WORD32 *msFlags = pstr_psy_out->psy_out_element.tools_info.ms_mask; + WORD32 *ms_flags = pstr_psy_out->psy_out_element.tools_info.ms_mask; ptr_sfb_offset[0] = pstr_psy_out->psy_out_ch[pstr_element_info.channel_index[0]]->sfb_offsets; @@ -753,7 +758,7 @@ IA_ERRORCODE ia_enhaacplus_enc_write_bitstream( tns_info[1] = pstr_psy_out->psy_out_ch[pstr_element_info.channel_index[1]]->tns_info; err_code = ia_enhaacplus_enc_write_channel_pair_element( - pstr_element_info.instance_tag, ms_digest, msFlags, ptr_sfb_offset, + pstr_element_info.instance_tag, ms_digest, ms_flags, ptr_sfb_offset, pstr_qc_out->qc_channel[pstr_element_info.channel_index[0]], pstr_bit_stream_handle, aot, tns_info, pstr_aac_tables); if (err_code != IA_NO_ERROR) { @@ -821,7 +826,6 @@ IA_ERRORCODE ia_enhaacplus_enc_write_bitstream( if (frame_bits != pstr_qc_out->tot_static_bits_used + pstr_qc_out->tot_dyn_bits_used + pstr_qc_out->tot_anc_bits_used + +pstr_qc_out->total_fill_bits + pstr_qc_out->align_bits) { - // return -1; } return IA_NO_ERROR; diff --git a/encoder/libxaacenc.cmake b/encoder/libxaacenc.cmake index d94f935..d2a7193 100644 --- a/encoder/libxaacenc.cmake +++ b/encoder/libxaacenc.cmake @@ -2,9 +2,37 @@ list( APPEND LIBXAACENC_SRCS + "${XAAC_ROOT}/encoder/iusace_acelp_enc.c" + "${XAAC_ROOT}/encoder/iusace_acelp_rom.c" + "${XAAC_ROOT}/encoder/iusace_acelp_tools.c" + "${XAAC_ROOT}/encoder/iusace_arith_enc.c" + "${XAAC_ROOT}/encoder/iusace_avq_enc.c" + "${XAAC_ROOT}/encoder/iusace_avq_rom.c" "${XAAC_ROOT}/encoder/iusace_bitbuffer.c" + "${XAAC_ROOT}/encoder/iusace_block_switch.c" + "${XAAC_ROOT}/encoder/iusace_enc_fac.c" + "${XAAC_ROOT}/encoder/iusace_enc_main.c" + "${XAAC_ROOT}/encoder/iusace_esbr_inter_tes.c" + "${XAAC_ROOT}/encoder/iusace_esbr_pvc.c" + "${XAAC_ROOT}/encoder/iusace_esbr_pvc_rom.c" + "${XAAC_ROOT}/encoder/iusace_esbr_rom.c" + "${XAAC_ROOT}/encoder/iusace_fd_fac.c" "${XAAC_ROOT}/encoder/iusace_fft.c" + "${XAAC_ROOT}/encoder/iusace_lpc.c" + "${XAAC_ROOT}/encoder/iusace_lpc_avq.c" + "${XAAC_ROOT}/encoder/iusace_lpd_enc.c" + "${XAAC_ROOT}/encoder/iusace_lpd_rom.c" + "${XAAC_ROOT}/encoder/iusace_lpd_utils.c" + "${XAAC_ROOT}/encoder/iusace_ms.c" + "${XAAC_ROOT}/encoder/iusace_psy_rom.c" + "${XAAC_ROOT}/encoder/iusace_psy_mod.c" + "${XAAC_ROOT}/encoder/iusace_psy_utils.c" "${XAAC_ROOT}/encoder/iusace_rom.c" + "${XAAC_ROOT}/encoder/iusace_tcx_enc.c" + "${XAAC_ROOT}/encoder/iusace_tcx_mdct.c" + "${XAAC_ROOT}/encoder/iusace_tns_usac.c" + "${XAAC_ROOT}/encoder/iusace_windowing.c" + "${XAAC_ROOT}/encoder/iusace_write_bitstream.c" "${XAAC_ROOT}/encoder/ixheaace_adjust_threshold.c" "${XAAC_ROOT}/encoder/ixheaace_api.c" "${XAAC_ROOT}/encoder/ixheaace_asc_write.c" @@ -16,9 +44,15 @@ list( "${XAAC_ROOT}/encoder/ixheaace_calc_ms_band_energy.c" "${XAAC_ROOT}/encoder/ixheaace_channel_map.c" "${XAAC_ROOT}/encoder/ixheaace_common_rom.c" + "${XAAC_ROOT}/encoder/ixheaace_cplx_pred.c" "${XAAC_ROOT}/encoder/ixheaace_dynamic_bits.c" "${XAAC_ROOT}/encoder/ixheaace_enc_init.c" "${XAAC_ROOT}/encoder/ixheaace_enc_main.c" + "${XAAC_ROOT}/encoder/ixheaace_fd_enc.c" + "${XAAC_ROOT}/encoder/ixheaace_fd_mdct.c" + "${XAAC_ROOT}/encoder/ixheaace_fd_qc_adjthr.c" + "${XAAC_ROOT}/encoder/ixheaace_fd_qc_util.c" + "${XAAC_ROOT}/encoder/ixheaace_fd_quant.c" "${XAAC_ROOT}/encoder/ixheaace_fft.c" "${XAAC_ROOT}/encoder/ixheaace_group_data.c" "${XAAC_ROOT}/encoder/ixheaace_huffman_rom.c" @@ -46,6 +80,7 @@ list( "${XAAC_ROOT}/encoder/ixheaace_mps_tree.c" "${XAAC_ROOT}/encoder/ixheaace_mps_vector_functions.c" "${XAAC_ROOT}/encoder/ixheaace_ms_stereo.c" + "${XAAC_ROOT}/encoder/ixheaace_nf.c" "${XAAC_ROOT}/encoder/ixheaace_ps_bitenc.c" "${XAAC_ROOT}/encoder/ixheaace_ps_enc.c" "${XAAC_ROOT}/encoder/ixheaace_ps_enc_init.c" @@ -68,6 +103,8 @@ list( "${XAAC_ROOT}/encoder/ixheaace_sbr_frame_info_gen.c" "${XAAC_ROOT}/encoder/ixheaace_sbr_freq_scaling.c" "${XAAC_ROOT}/encoder/ixheaace_sbr_hbe_dft_trans.c" + "${XAAC_ROOT}/encoder/ixheaace_sbr_hbe_fft_ifft_32x32.c" + "${XAAC_ROOT}/encoder/ixheaace_sbr_hbe_polyphase.c" "${XAAC_ROOT}/encoder/ixheaace_sbr_hbe_trans.c" "${XAAC_ROOT}/encoder/ixheaace_sbr_inv_filtering_estimation.c" "${XAAC_ROOT}/encoder/ixheaace_sbr_main.c" @@ -83,6 +120,8 @@ list( "${XAAC_ROOT}/encoder/ixheaace_sbr_tran_det_hp.c" "${XAAC_ROOT}/encoder/ixheaace_sbr_write_bitstream.c" "${XAAC_ROOT}/encoder/ixheaace_sf_estimation.c" + "${XAAC_ROOT}/encoder/ixheaace_signal_classifier.c" + "${XAAC_ROOT}/encoder/ixheaace_signal_classifier_rom.c" "${XAAC_ROOT}/encoder/ixheaace_static_bits.c" "${XAAC_ROOT}/encoder/ixheaace_stereo_preproc.c" "${XAAC_ROOT}/encoder/ixheaace_tns.c" @@ -91,8 +130,10 @@ list( "${XAAC_ROOT}/encoder/ixheaace_tns_params.c" "${XAAC_ROOT}/encoder/ixheaace_write_adts_adif.c" "${XAAC_ROOT}/encoder/ixheaace_write_bitstream.c") - -set(LIBXAACDEC_INCLUDES ${XAAC_ROOT}/encoder) + +set(LIBXAACENC_INCLUDES ${XAAC_ROOT}/encoder ${XAAC_ROOT}/encoder/drc_src) include_directories(${LIBXAACENC_INCLUDES}) +include("${XAAC_ROOT}/encoder/drc_src/libxaacenc_drc.cmake") + add_library(libxaacenc STATIC ${LIBXAACENC_SRCS} ${LIBXAAC_COMMON_SRCS}) \ No newline at end of file diff --git a/fuzzer/xaac_enc_fuzzer.cmake b/fuzzer/xaac_enc_fuzzer.cmake index 103d285..fe17d48 100644 --- a/fuzzer/xaac_enc_fuzzer.cmake +++ b/fuzzer/xaac_enc_fuzzer.cmake @@ -1,4 +1,4 @@ -list(APPEND XAAC_ENC_FUZZER_SRCS "${XAAC_ROOT}/fuzzer/xaac_enc_fuzzer.cpp" ) +list(APPEND XAAC_ENC_FUZZER_SRCS "${XAAC_ROOT}/fuzzer/xaac_enc_fuzzer.cpp") set(LIBXAACENC_INCLUDES ${XAAC_ROOT}/encoder ${XAAC_ROOT}/test/encoder ${XAAC_ROOT}/common) diff --git a/fuzzer/xaac_enc_fuzzer.cpp b/fuzzer/xaac_enc_fuzzer.cpp index f4ee507..68895f3 100644 --- a/fuzzer/xaac_enc_fuzzer.cpp +++ b/fuzzer/xaac_enc_fuzzer.cpp @@ -24,23 +24,319 @@ #include #include #include + +extern "C" { #include "ixheaac_type_def.h" #include "ixheaace_aac_constants.h" #include "ixheaac_error_standards.h" - -extern "C" { +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" #include "ixheaace_api.h" -} #include "ixheaace_memory_standards.h" #include "ixheaace_config_params.h" +} /*****************************************************************************/ /* Constant hash defines */ /*****************************************************************************/ #define MAX_MEM_ALLOCS 100 +#define IA_MAX_CMD_LINE_LENGTH 300 +#define DRC_CONFIG_FILE "impd_drc_config_params.txt" +#ifndef TRUE +#define TRUE (1) +#endif +#ifndef FALSE +#define FALSE (0) +#endif + +WORD8 pb_drc_file_path[IA_MAX_CMD_LINE_LENGTH] = ""; +FILE *g_drc_inp = NULL; pVOID malloc_global(UWORD32 size, UWORD32 alignment) { return malloc(size + alignment); } +static FLOAT32 impd_drc_get_float_value(FILE *fp) { + WORD32 i = 0; + FLOAT32 result = 0.0f; + CHAR8 line[1024]; + pCHAR8 retval; + retval = fgets(line, sizeof(line), fp); + if (retval) { + pCHAR8 c = line; + while ((line[0] == '#' || line[0] == '\n') && (retval != NULL)) { + retval = fgets(line, sizeof(line), fp); + } + while (line[i] != ':') { + c++; + i++; + } + c++; + result = (FLOAT32)atof(c); + } + return result; +} + +static WORD32 impd_drc_get_integer_value(FILE *fp) { + WORD32 i = 0; + WORD32 result = 0; + CHAR8 line[1024]; + pCHAR8 retval; + retval = fgets(line, sizeof(line), fp); + if (retval) { + pCHAR8 c = line; + while ((line[0] == '#' || line[0] == '\n') && (retval != NULL)) { + retval = fgets(line, sizeof(line), fp); + } + while (line[i] != ':') { + c++; + i++; + } + c++; + if (c[0] == '0' && c[1] == 'x') { + result = (WORD32)strtol(c, NULL, 16); + } else { + result = atoi(c); + } + } + return result; +} + +static VOID ixheaace_read_drc_config_params( + FILE *fp, ia_drc_enc_params_struct *pstr_enc_params, + ia_drc_uni_drc_config_struct *pstr_uni_drc_config, + ia_drc_loudness_info_set_struct *pstr_enc_loudness_info_set, + ia_drc_uni_drc_gain_ext_struct *pstr_enc_gain_extension) { + WORD32 n, g, s, m, ch, p; + WORD32 gain_set_channels; + + pstr_enc_params->delay_mode = DELAY_MODE_REGULAR_DELAY; + pstr_uni_drc_config->sample_rate_present = 1; + pstr_uni_drc_config->str_drc_coefficients_uni_drc->drc_frame_size_present = 0; + pstr_uni_drc_config->loudness_info_set_present = 1; + + /*********** str_drc_instructions_uni_drc *************/ + + pstr_uni_drc_config->drc_instructions_uni_drc_count = impd_drc_get_integer_value(fp); + for (n = 0; n < pstr_uni_drc_config->drc_instructions_uni_drc_count; n++) { + ia_drc_instructions_uni_drc *pstr_drc_instructions_uni_drc = + &pstr_uni_drc_config->str_drc_instructions_uni_drc[n]; + pstr_drc_instructions_uni_drc->drc_set_id = n + 1; + pstr_drc_instructions_uni_drc->downmix_id = impd_drc_get_integer_value(fp); + pstr_drc_instructions_uni_drc->additional_downmix_id_present = 0; + pstr_drc_instructions_uni_drc->additional_downmix_id_count = 0; + pstr_drc_instructions_uni_drc->drc_location = 1; + pstr_drc_instructions_uni_drc->depends_on_drc_set_present = 0; + pstr_drc_instructions_uni_drc->depends_on_drc_set = 0; + pstr_drc_instructions_uni_drc->no_independent_use = 0; + pstr_drc_instructions_uni_drc->drc_set_effect = impd_drc_get_integer_value(fp); + pstr_drc_instructions_uni_drc->drc_set_target_loudness_present = 0; + pstr_drc_instructions_uni_drc->drc_set_target_loudness_value_upper = 0; + pstr_drc_instructions_uni_drc->drc_set_target_loudness_value_lower_present = 0; + pstr_drc_instructions_uni_drc->drc_set_target_loudness_value_lower = 0; + + gain_set_channels = impd_drc_get_integer_value(fp); + for (ch = 0; ch < gain_set_channels; ch++) { + pstr_drc_instructions_uni_drc->gain_set_index[ch] = impd_drc_get_integer_value(fp); + } + for (; ch < MAX_CHANNEL_COUNT; ch++) { + pstr_drc_instructions_uni_drc->gain_set_index[ch] = + pstr_drc_instructions_uni_drc->gain_set_index[gain_set_channels - 1]; + } + + pstr_drc_instructions_uni_drc->num_drc_channel_groups = impd_drc_get_integer_value(fp); + + for (g = 0; g < pstr_drc_instructions_uni_drc->num_drc_channel_groups; g++) { + pstr_drc_instructions_uni_drc->str_gain_modifiers[g].gain_scaling_present[0] = 0; + pstr_drc_instructions_uni_drc->str_gain_modifiers[g].attenuation_scaling[0] = 1.5f; + pstr_drc_instructions_uni_drc->str_gain_modifiers[g].amplification_scaling[0] = 1.5f; + pstr_drc_instructions_uni_drc->str_gain_modifiers[g].gain_offset_present[0] = 0; + pstr_drc_instructions_uni_drc->str_gain_modifiers[g].gain_offset[0] = 16.0f; + } + + pstr_drc_instructions_uni_drc->limiter_peak_target_present = 0; + pstr_drc_instructions_uni_drc->limiter_peak_target = 0.0f; + pstr_drc_instructions_uni_drc->drc_instructions_type = 0; + pstr_drc_instructions_uni_drc->mae_group_id = 0; + pstr_drc_instructions_uni_drc->mae_group_preset_id = 0; + } + + /*********** str_drc_coefficients_uni_drc *************/ + + pstr_uni_drc_config->drc_coefficients_uni_drc_count = impd_drc_get_integer_value(fp); + for (n = 0; n < pstr_uni_drc_config->drc_coefficients_uni_drc_count; n++) { + ia_drc_coefficients_uni_drc_struct *pstr_drc_coefficients_uni_drc = + &pstr_uni_drc_config->str_drc_coefficients_uni_drc[n]; + pstr_drc_coefficients_uni_drc->drc_location = 1; + pstr_drc_coefficients_uni_drc->gain_set_count = impd_drc_get_integer_value(fp); + + for (s = 0; s < pstr_drc_coefficients_uni_drc->gain_set_count; s++) { + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].gain_coding_profile = 0; + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].gain_interpolation_type = 1; + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].full_frame = 0; + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].time_alignment = 0; + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].time_delta_min_present = 0; + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].band_count = + impd_drc_get_integer_value(fp); + if (pstr_drc_coefficients_uni_drc->str_gain_set_params[s].band_count == 1) { + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].gain_params[0].nb_points = + impd_drc_get_integer_value(fp); + for (p = 0; + p < pstr_drc_coefficients_uni_drc->str_gain_set_params[s].gain_params[0].nb_points; + p++) { + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].gain_params[0].gain_points[p].x = + impd_drc_get_float_value(fp); + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].gain_params[0].gain_points[p].y = + impd_drc_get_float_value(fp); + } + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].gain_params[0].width = + impd_drc_get_float_value(fp); + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].gain_params[0].attack = + impd_drc_get_float_value(fp); + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].gain_params[0].decay = + impd_drc_get_float_value(fp); + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].gain_params[0].drc_characteristic = + 0; + pstr_drc_coefficients_uni_drc->str_gain_set_params[s] + .gain_params[0] + .crossover_freq_index = 0; + } else { + for (m = 0; m < pstr_drc_coefficients_uni_drc->str_gain_set_params[s].band_count; m++) { + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].gain_params[m].nb_points = + impd_drc_get_integer_value(fp); + for (p = 0; + p < pstr_drc_coefficients_uni_drc->str_gain_set_params[s].gain_params[m].nb_points; + p++) { + pstr_drc_coefficients_uni_drc->str_gain_set_params[s] + .gain_params[m] + .gain_points[p] + .x = impd_drc_get_float_value(fp); + pstr_drc_coefficients_uni_drc->str_gain_set_params[s] + .gain_params[m] + .gain_points[p] + .y = impd_drc_get_float_value(fp); + } + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].gain_params[m].width = + impd_drc_get_float_value(fp); + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].gain_params[m].attack = + impd_drc_get_float_value(fp); + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].gain_params[m].decay = + impd_drc_get_float_value(fp); + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].drc_band_type = 0; + pstr_drc_coefficients_uni_drc->str_gain_set_params[s] + .gain_params[m] + .start_sub_band_index = impd_drc_get_integer_value(fp); + pstr_drc_coefficients_uni_drc->str_gain_set_params[s] + .gain_params[m] + .drc_characteristic = 0; + pstr_drc_coefficients_uni_drc->str_gain_set_params[s] + .gain_params[m] + .crossover_freq_index = 0; + } + } + } + } + + pstr_enc_loudness_info_set->loudness_info_count = impd_drc_get_integer_value(fp); + for (n = 0; n < pstr_enc_loudness_info_set->loudness_info_count; n++) { + pstr_enc_loudness_info_set->str_loudness_info[n].drc_set_id = impd_drc_get_integer_value(fp); + pstr_enc_loudness_info_set->str_loudness_info[n].downmix_id = impd_drc_get_integer_value(fp); + pstr_enc_loudness_info_set->str_loudness_info[n].sample_peak_level_present = + impd_drc_get_integer_value(fp); + if (1 == pstr_enc_loudness_info_set->str_loudness_info[n].sample_peak_level_present) { + pstr_enc_loudness_info_set->str_loudness_info[n].sample_peak_level = + impd_drc_get_float_value(fp); + } + pstr_enc_loudness_info_set->str_loudness_info[n].true_peak_level_present = + impd_drc_get_integer_value(fp); + if (1 == pstr_enc_loudness_info_set->str_loudness_info[n].true_peak_level_present) { + pstr_enc_loudness_info_set->str_loudness_info[n].true_peak_level = + impd_drc_get_float_value(fp); + pstr_enc_loudness_info_set->str_loudness_info[n].true_peak_level_measurement_system = + impd_drc_get_integer_value(fp); + pstr_enc_loudness_info_set->str_loudness_info[n].true_peak_level_reliability = + impd_drc_get_integer_value(fp); + } + pstr_enc_loudness_info_set->str_loudness_info[n].measurement_count = + impd_drc_get_integer_value(fp); + + for (m = 0; m < pstr_enc_loudness_info_set->str_loudness_info[n].measurement_count; m++) { + pstr_enc_loudness_info_set->str_loudness_info[n].str_loudness_measure[m].method_definition = + impd_drc_get_integer_value(fp); + pstr_enc_loudness_info_set->str_loudness_info[n].str_loudness_measure[m].method_value = + impd_drc_get_float_value(fp); + pstr_enc_loudness_info_set->str_loudness_info[n] + .str_loudness_measure[m] + .measurement_system = impd_drc_get_integer_value(fp); + pstr_enc_loudness_info_set->str_loudness_info[n].str_loudness_measure[m].reliability = + impd_drc_get_integer_value(fp); + } + } + + pstr_enc_loudness_info_set->loudness_info_album_count = impd_drc_get_integer_value(fp); + for (n = 0; n < pstr_enc_loudness_info_set->loudness_info_album_count; n++) { + pstr_enc_loudness_info_set->str_loudness_info_album[n].drc_set_id = + impd_drc_get_integer_value(fp); + pstr_enc_loudness_info_set->str_loudness_info_album[n].downmix_id = + impd_drc_get_integer_value(fp); + pstr_enc_loudness_info_set->str_loudness_info_album[n].sample_peak_level_present = + impd_drc_get_integer_value(fp); + if (1 == pstr_enc_loudness_info_set->str_loudness_info_album[n].sample_peak_level_present) { + pstr_enc_loudness_info_set->str_loudness_info_album[n].sample_peak_level = + impd_drc_get_float_value(fp); + } + pstr_enc_loudness_info_set->str_loudness_info_album[n].true_peak_level_present = + impd_drc_get_integer_value(fp); + if (1 == pstr_enc_loudness_info_set->str_loudness_info_album[n].true_peak_level_present) { + pstr_enc_loudness_info_set->str_loudness_info_album[n].true_peak_level = + impd_drc_get_float_value(fp); + pstr_enc_loudness_info_set->str_loudness_info_album[n].true_peak_level_measurement_system = + impd_drc_get_integer_value(fp); + pstr_enc_loudness_info_set->str_loudness_info_album[n].true_peak_level_reliability = + impd_drc_get_integer_value(fp); + } + pstr_enc_loudness_info_set->str_loudness_info_album[n].measurement_count = + impd_drc_get_integer_value(fp); + + for (m = 0; m < pstr_enc_loudness_info_set->str_loudness_info_album[n].measurement_count; + m++) { + pstr_enc_loudness_info_set->str_loudness_info_album[n] + .str_loudness_measure[m] + .method_definition = impd_drc_get_integer_value(fp); /* 0 = program loudness */ + pstr_enc_loudness_info_set->str_loudness_info_album[n] + .str_loudness_measure[m] + .method_value = impd_drc_get_float_value(fp); + pstr_enc_loudness_info_set->str_loudness_info_album[n] + .str_loudness_measure[m] + .measurement_system = impd_drc_get_integer_value(fp); /* 2 = ITU-R BS.1770-3 */ + pstr_enc_loudness_info_set->str_loudness_info_album[n].str_loudness_measure[m].reliability = + impd_drc_get_integer_value(fp); /* 0 = unknown */ + } + } + + /*********** str_channel_layout *************/ + + pstr_uni_drc_config->str_channel_layout.layout_signaling_present = 0; + pstr_uni_drc_config->str_channel_layout.defined_layout = 0; + pstr_uni_drc_config->str_channel_layout.speaker_position[0] = 0; + + /*********** str_downmix_instructions *************/ + + pstr_uni_drc_config->downmix_instructions_count = + 0; // pstr_ext_cfg_downmix_input->downmix_id_count; + for (n = 0; n < pstr_uni_drc_config->downmix_instructions_count; n++) { + pstr_uni_drc_config->str_downmix_instructions[n].target_layout = + impd_drc_get_integer_value(fp); + pstr_uni_drc_config->str_downmix_instructions[n].downmix_coefficients_present = + impd_drc_get_integer_value(fp); + } + + pstr_uni_drc_config->drc_description_basic_present = 0; + pstr_uni_drc_config->uni_drc_config_ext_present = 0; + pstr_enc_loudness_info_set->loudness_info_set_ext_present = 0; + pstr_enc_gain_extension->uni_drc_gain_ext_present = 0; +} + static VOID ixheaace_fuzzer_flag(ixheaace_input_config *pstr_in_cfg, WORD8 *data) { // Set Default value for AAC config structure memset(pstr_in_cfg, 0, sizeof(*pstr_in_cfg)); @@ -61,6 +357,66 @@ static VOID ixheaace_fuzzer_flag(ixheaace_input_config *pstr_in_cfg, WORD8 *data pstr_in_cfg->aac_config.bitreservoir_size = *(WORD16 *)(data + 19); pstr_in_cfg->i_mps_tree_config = *(WORD8 *)(data + 20); pstr_in_cfg->i_channels_mask = *(WORD8 *)(data + 21); + pstr_in_cfg->cplx_pred = *(WORD8 *)(data + 22); + pstr_in_cfg->usac_en = *(WORD8 *)(data + 23); + pstr_in_cfg->ccfl_idx = *(WORD8 *)(data + 24); + pstr_in_cfg->pvc_active = *(WORD8 *)(data + 25); + pstr_in_cfg->harmonic_sbr = *(WORD8 *)(data + 26); + pstr_in_cfg->hq_esbr = *(WORD8 *)(data + 27); + pstr_in_cfg->use_drc_element = *(WORD8 *)(data + 28); + pstr_in_cfg->inter_tes_active = *(WORD8 *)(data + 39); + pstr_in_cfg->codec_mode = *(WORD8 *)(data + 30); + + /* DRC */ + if (pstr_in_cfg->use_drc_element == 1 /*&& pstr_in_cfg->aot == AOT_USAC*/) { + LOOPIDX k; + CHAR8 drc_config_file_name[IA_MAX_CMD_LINE_LENGTH]; + strcpy(drc_config_file_name, DRC_CONFIG_FILE); + g_drc_inp = fopen(drc_config_file_name, "rt"); + + if (!g_drc_inp) { + // Disable DRC + pstr_in_cfg->use_drc_element = 0; + } + + if (g_drc_inp != 0) { + memset(&pstr_in_cfg->str_drc_cfg, 0, sizeof(ia_drc_input_config)); + ixheaace_read_drc_config_params(g_drc_inp, &pstr_in_cfg->str_drc_cfg.str_enc_params, + &pstr_in_cfg->str_drc_cfg.str_uni_drc_config, + &pstr_in_cfg->str_drc_cfg.str_enc_loudness_info_set, + &pstr_in_cfg->str_drc_cfg.str_enc_gain_extension); + + pstr_in_cfg->str_drc_cfg.str_enc_params.gain_sequence_present = FALSE; + for (k = 0; k < pstr_in_cfg->str_drc_cfg.str_uni_drc_config.drc_coefficients_uni_drc_count; + k++) { + if (pstr_in_cfg->str_drc_cfg.str_uni_drc_config.str_drc_coefficients_uni_drc[k] + .drc_location == 1) { + if (pstr_in_cfg->str_drc_cfg.str_uni_drc_config.str_drc_coefficients_uni_drc[k] + .gain_set_count > 0) { + pstr_in_cfg->str_drc_cfg.str_enc_params.gain_sequence_present = TRUE; + break; + } + } + } + + if (pstr_in_cfg->str_drc_cfg.str_enc_params.gain_sequence_present == FALSE) { + for (k = 0; k < pstr_in_cfg->str_drc_cfg.str_uni_drc_config.str_uni_drc_config_ext + .drc_coefficients_uni_drc_v1_count; + k++) { + if (pstr_in_cfg->str_drc_cfg.str_uni_drc_config.str_uni_drc_config_ext + .str_drc_coefficients_uni_drc_v1[k] + .drc_location == 1) { + if (pstr_in_cfg->str_drc_cfg.str_uni_drc_config.str_uni_drc_config_ext + .str_drc_coefficients_uni_drc_v1[k] + .gain_sequence_count > 0) { + pstr_in_cfg->str_drc_cfg.str_enc_params.gain_sequence_present = TRUE; + break; + } + } + } + } + } + } } VOID free_global(pVOID ptr) { @@ -120,8 +476,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { file_data_size = size; data_size_left = file_data_size; bytes_consumed = 0; + ixheaace_fuzzer_flag(&pstr_enc_api->input_config, (WORD8 *)data); - bytes_consumed = 22; + bytes_consumed = 31; { if (pstr_in_cfg->aot == AOT_AAC_LC || pstr_in_cfg->aot == AOT_SBR || diff --git a/test/Android.bp b/test/Android.bp index 035f418..61dd091 100644 --- a/test/Android.bp +++ b/test/Android.bp @@ -49,15 +49,16 @@ cc_test { cflags: [ "-O3", - "-D_CRT_SECURE_NO_WARNINGS", "-D_X86_", ], include_dirs: [ "external/libxaac/encoder/", + "external/libxaac/encoder/drc_src/", ], srcs: [ + "encoder/impd_drc_user_config.c", "encoder/ixheaace_error.c", "encoder/ixheaace_testbench.c", "encoder/ixheaace_wav_reader.c", diff --git a/test/encoder/impd_drc_config_params.txt b/test/encoder/impd_drc_config_params.txt new file mode 100644 index 0000000..699f41a --- /dev/null +++ b/test/encoder/impd_drc_config_params.txt @@ -0,0 +1,232 @@ +#####str_drc_instructions_uni_drc##### +drc_instructions_uni_drc_count:8 +#n=0 +downmix_id:0 +#Different drc_effect values are present in impeghe_drc_uni_drc.h file with prefix EFFECT_BIT_ +drc_set_effect:0x0001 +gain_set_channels:10 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +num_drc_channel_groups:1 +#n=1 +downmix_id:0 +#Different drc_effect values are present in impeghe_drc_uni_drc.h file with prefix EFFECT_BIT_ +drc_set_effect:0x0002 +gain_set_channels:10 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +num_drc_channel_groups:1 +#n=2 +downmix_id:0 +#Different drc_effect values are present in impeghe_drc_uni_drc.h file with prefix EFFECT_BIT_ +drc_set_effect:0x0004 +gain_set_channels:10 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +num_drc_channel_groups:1 +#n=3 +downmix_id:0 +#Different drc_effect values are present in impeghe_drc_uni_drc.h file with prefix EFFECT_BIT_ +drc_set_effect:0x0008 +gain_set_channels:10 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +num_drc_channel_groups:1 +#n=4 +downmix_id:0 +#Different drc_effect values are present in impeghe_drc_uni_drc.h file with prefix EFFECT_BIT_ +drc_set_effect:0x0010 +gain_set_channels:10 +gain_set_index:1 +gain_set_index:1 +gain_set_index:1 +gain_set_index:1 +gain_set_index:1 +gain_set_index:1 +gain_set_index:1 +gain_set_index:1 +gain_set_index:1 +gain_set_index:1 +num_drc_channel_groups:1 +#n=5 +downmix_id:0 +#Different drc_effect values are present in impeghe_drc_uni_drc.h file with prefix EFFECT_BIT_ +drc_set_effect:0x0020 +gain_set_channels:10 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +num_drc_channel_groups:1 +#n=6 +downmix_id:0 +#Different drc_effect values are present in impeghe_drc_uni_drc.h file with prefix EFFECT_BIT_ +drc_set_effect:0x0040 +gain_set_channels:10 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +num_drc_channel_groups:1 +#n=7 +downmix_id:0 +#Different drc_effect values are present in impeghe_drc_uni_drc.h file with prefix EFFECT_BIT_ +drc_set_effect:0x0080 +gain_set_channels:10 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +gain_set_index:0 +num_drc_channel_groups:1 +#####str_drc_coefficients_uni_drc##### +drc_coefficients_uni_drc_count:1 +#n=0 +gain_set_count:2 +#s=0 +band_count:1 +#gain parameters m=0 +nb_points:3 +x:-60.0 +y:-40.0 +x:-30.0 +y:-30.0 +x:0.0 +y:-20.0 +width:0.01 +attack:2.0 +decay:5.0 +#end gain parameters +#s=1 +band_count:3 +#gain parameters m=0 +nb_points:2 +x:-50.0 +y:-50.0 +x:0.0 +y:-10.0 +width:0.01 +attack:2.0 +decay:5.0 +start_sub_band_index:0 +#end gain parameters +#gain parameters m=1 +nb_points:3 +x:-60.0 +y:-60.0 +x:-20.0 +y:-15.0 +x:0.0 +y:-5.0 +width:0.01 +attack:2.0 +decay:5.0 +start_sub_band_index:3 +#end gain parameters +#gain parameters m=2 +nb_points:3 +x:-80.0 +y:-80.0 +x:-30.0 +y:-60.0 +x:0.0 +y:-30.0 +width:0.01 +attack:2.0 +decay:5.0 +start_sub_band_index:44 +#end gain parameters +#loudness info parameters +loudness_info_count:1 +#n=0 +drc_set_id:1 +downmix_id:1 +sample_peak_level_present:1 +sample_peak_level:0.0 +true_peak_level_present:1 +true_peak_level:1.0 +true_peak_level_measurement_system:2 +true_peak_level_reliability:3 +measurement_count:2 +#m=0 +method_definition:1 +method_value:-10.0 +measurement_system:2 +reliability:3 +#m=1 +method_definition:3 +method_value:-6.0 +measurement_system:1 +reliability:3 +#end loudness info parameters +#loudness info album parameters +loudness_info_album_count:1 +#n=0 +drc_set_id:1 +downmix_id:1 +sample_peak_level_present:0 +#sample_peak_level: +true_peak_level_present:0 +#true_peak_level: +#true_peak_level_measurement_system: +#true_peak_level_reliability: +measurement_count:1 +#m=0 +method_definition:1 +method_value:-10.0 +measurement_system:2 +reliability:3 +#end loudness info album parameters +#####str_downmix_instructions##### +#n=0 +target_layout:0 +downmix_coefficients_present:0 diff --git a/test/encoder/impd_drc_user_config.c b/test/encoder/impd_drc_user_config.c new file mode 100644 index 0000000..58ee160 --- /dev/null +++ b/test/encoder/impd_drc_user_config.c @@ -0,0 +1,315 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#include +#include +#include +#include "ixheaac_type_def.h" +#include "iusace_bitbuffer.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" +#include "impd_drc_uni_drc_eq.h" +#include "impd_drc_uni_drc_filter_bank.h" +#include "impd_drc_gain_enc.h" +#include "impd_drc_struct_def.h" +#include "impd_drc_enc.h" +#include "impd_drc_user_config.h" + +static FLOAT32 impd_drc_get_float_value(FILE *fp) { + WORD32 i = 0; + FLOAT32 result = 0.0f; + CHAR8 line[1024]; + pCHAR8 retval; + retval = fgets(line, sizeof(line), fp); + if (retval) { + pCHAR8 c = line; + while ((line[0] == '#' || line[0] == '\n') && (retval != NULL)) { + retval = fgets(line, sizeof(line), fp); + } + while (line[i] != ':') { + c++; + i++; + } + c++; + result = (FLOAT32)atof(c); + } + return result; +} + +static WORD32 impd_drc_get_integer_value(FILE *fp) { + WORD32 i = 0; + WORD32 result = 0; + CHAR8 line[1024]; + pCHAR8 retval; + retval = fgets(line, sizeof(line), fp); + if (retval) { + pCHAR8 c = line; + while ((line[0] == '#' || line[0] == '\n') && (retval != NULL)) { + retval = fgets(line, sizeof(line), fp); + } + while (line[i] != ':') { + c++; + i++; + } + c++; + if (c[0] == '0' && c[1] == 'x') { + result = (WORD32)strtol(c, NULL, 16); + } else { + result = atoi(c); + } + } + return result; +} + +VOID ixheaace_read_drc_config_params(FILE *fp, ia_drc_enc_params_struct *pstr_enc_params, + ia_drc_uni_drc_config_struct *pstr_uni_drc_config, + ia_drc_loudness_info_set_struct *pstr_enc_loudness_info_set, + ia_drc_uni_drc_gain_ext_struct *pstr_enc_gain_extension) { + WORD32 n, g, s, m, ch, p; + WORD32 gain_set_channels; + + pstr_enc_params->delay_mode = DELAY_MODE_REGULAR_DELAY; + pstr_uni_drc_config->sample_rate_present = 1; + pstr_uni_drc_config->str_drc_coefficients_uni_drc->drc_frame_size_present = 0; + pstr_uni_drc_config->loudness_info_set_present = 1; + + /*********** str_drc_instructions_uni_drc *************/ + + pstr_uni_drc_config->drc_instructions_uni_drc_count = impd_drc_get_integer_value(fp); + for (n = 0; n < pstr_uni_drc_config->drc_instructions_uni_drc_count; n++) { + ia_drc_instructions_uni_drc *pstr_drc_instructions_uni_drc = + &pstr_uni_drc_config->str_drc_instructions_uni_drc[n]; + pstr_drc_instructions_uni_drc->drc_set_id = n + 1; + pstr_drc_instructions_uni_drc->downmix_id = impd_drc_get_integer_value(fp); + pstr_drc_instructions_uni_drc->additional_downmix_id_present = 0; + pstr_drc_instructions_uni_drc->additional_downmix_id_count = 0; + pstr_drc_instructions_uni_drc->drc_location = 1; + pstr_drc_instructions_uni_drc->depends_on_drc_set_present = 0; + pstr_drc_instructions_uni_drc->depends_on_drc_set = 0; + pstr_drc_instructions_uni_drc->no_independent_use = 0; + pstr_drc_instructions_uni_drc->drc_set_effect = impd_drc_get_integer_value(fp); + pstr_drc_instructions_uni_drc->drc_set_target_loudness_present = 0; + pstr_drc_instructions_uni_drc->drc_set_target_loudness_value_upper = 0; + pstr_drc_instructions_uni_drc->drc_set_target_loudness_value_lower_present = 0; + pstr_drc_instructions_uni_drc->drc_set_target_loudness_value_lower = 0; + + gain_set_channels = impd_drc_get_integer_value(fp); + for (ch = 0; ch < gain_set_channels; ch++) { + pstr_drc_instructions_uni_drc->gain_set_index[ch] = impd_drc_get_integer_value(fp); + } + for (; ch < MAX_CHANNEL_COUNT; ch++) { + pstr_drc_instructions_uni_drc->gain_set_index[ch] = + pstr_drc_instructions_uni_drc->gain_set_index[gain_set_channels - 1]; + } + + pstr_drc_instructions_uni_drc->num_drc_channel_groups = impd_drc_get_integer_value(fp); + + for (g = 0; g < pstr_drc_instructions_uni_drc->num_drc_channel_groups; g++) { + pstr_drc_instructions_uni_drc->str_gain_modifiers[g].gain_scaling_present[0] = 0; + pstr_drc_instructions_uni_drc->str_gain_modifiers[g].attenuation_scaling[0] = 1.5f; + pstr_drc_instructions_uni_drc->str_gain_modifiers[g].amplification_scaling[0] = 1.5f; + pstr_drc_instructions_uni_drc->str_gain_modifiers[g].gain_offset_present[0] = 0; + pstr_drc_instructions_uni_drc->str_gain_modifiers[g].gain_offset[0] = 16.0f; + } + + pstr_drc_instructions_uni_drc->limiter_peak_target_present = 0; + pstr_drc_instructions_uni_drc->limiter_peak_target = 0.0f; + pstr_drc_instructions_uni_drc->drc_instructions_type = 0; + pstr_drc_instructions_uni_drc->mae_group_id = 0; + pstr_drc_instructions_uni_drc->mae_group_preset_id = 0; + } + + /*********** str_drc_coefficients_uni_drc *************/ + + pstr_uni_drc_config->drc_coefficients_uni_drc_count = impd_drc_get_integer_value(fp); + for (n = 0; n < pstr_uni_drc_config->drc_coefficients_uni_drc_count; n++) { + ia_drc_coefficients_uni_drc_struct *pstr_drc_coefficients_uni_drc = + &pstr_uni_drc_config->str_drc_coefficients_uni_drc[n]; + pstr_drc_coefficients_uni_drc->drc_location = 1; + pstr_drc_coefficients_uni_drc->gain_set_count = impd_drc_get_integer_value(fp); + + for (s = 0; s < pstr_drc_coefficients_uni_drc->gain_set_count; s++) { + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].gain_coding_profile = 0; + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].gain_interpolation_type = 1; + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].full_frame = 0; + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].time_alignment = 0; + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].time_delta_min_present = 0; + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].band_count = + impd_drc_get_integer_value(fp); + if (pstr_drc_coefficients_uni_drc->str_gain_set_params[s].band_count == 1) { + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].gain_params[0].nb_points = + impd_drc_get_integer_value(fp); + for (p = 0; + p < pstr_drc_coefficients_uni_drc->str_gain_set_params[s].gain_params[0].nb_points; + p++) { + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].gain_params[0].gain_points[p].x = + impd_drc_get_float_value(fp); + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].gain_params[0].gain_points[p].y = + impd_drc_get_float_value(fp); + } + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].gain_params[0].width = + impd_drc_get_float_value(fp); + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].gain_params[0].attack = + impd_drc_get_float_value(fp); + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].gain_params[0].decay = + impd_drc_get_float_value(fp); + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].gain_params[0].drc_characteristic = + 0; + pstr_drc_coefficients_uni_drc->str_gain_set_params[s] + .gain_params[0] + .crossover_freq_index = 0; + } else { + for (m = 0; m < pstr_drc_coefficients_uni_drc->str_gain_set_params[s].band_count; m++) { + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].gain_params[m].nb_points = + impd_drc_get_integer_value(fp); + for (p = 0; + p < pstr_drc_coefficients_uni_drc->str_gain_set_params[s].gain_params[m].nb_points; + p++) { + pstr_drc_coefficients_uni_drc->str_gain_set_params[s] + .gain_params[m] + .gain_points[p] + .x = impd_drc_get_float_value(fp); + pstr_drc_coefficients_uni_drc->str_gain_set_params[s] + .gain_params[m] + .gain_points[p] + .y = impd_drc_get_float_value(fp); + } + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].gain_params[m].width = + impd_drc_get_float_value(fp); + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].gain_params[m].attack = + impd_drc_get_float_value(fp); + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].gain_params[m].decay = + impd_drc_get_float_value(fp); + pstr_drc_coefficients_uni_drc->str_gain_set_params[s].drc_band_type = 0; + pstr_drc_coefficients_uni_drc->str_gain_set_params[s] + .gain_params[m] + .start_sub_band_index = impd_drc_get_integer_value(fp); + pstr_drc_coefficients_uni_drc->str_gain_set_params[s] + .gain_params[m] + .drc_characteristic = 0; + pstr_drc_coefficients_uni_drc->str_gain_set_params[s] + .gain_params[m] + .crossover_freq_index = 0; + } + } + } + } + + pstr_enc_loudness_info_set->loudness_info_count = impd_drc_get_integer_value(fp); + for (n = 0; n < pstr_enc_loudness_info_set->loudness_info_count; n++) { + pstr_enc_loudness_info_set->str_loudness_info[n].drc_set_id = impd_drc_get_integer_value(fp); + pstr_enc_loudness_info_set->str_loudness_info[n].downmix_id = impd_drc_get_integer_value(fp); + pstr_enc_loudness_info_set->str_loudness_info[n].sample_peak_level_present = + impd_drc_get_integer_value(fp); + if (1 == pstr_enc_loudness_info_set->str_loudness_info[n].sample_peak_level_present) { + pstr_enc_loudness_info_set->str_loudness_info[n].sample_peak_level = + impd_drc_get_float_value(fp); + } + pstr_enc_loudness_info_set->str_loudness_info[n].true_peak_level_present = + impd_drc_get_integer_value(fp); + if (1 == pstr_enc_loudness_info_set->str_loudness_info[n].true_peak_level_present) { + pstr_enc_loudness_info_set->str_loudness_info[n].true_peak_level = + impd_drc_get_float_value(fp); + pstr_enc_loudness_info_set->str_loudness_info[n].true_peak_level_measurement_system = + impd_drc_get_integer_value(fp); + pstr_enc_loudness_info_set->str_loudness_info[n].true_peak_level_reliability = + impd_drc_get_integer_value(fp); + } + pstr_enc_loudness_info_set->str_loudness_info[n].measurement_count = + impd_drc_get_integer_value(fp); + + for (m = 0; m < pstr_enc_loudness_info_set->str_loudness_info[n].measurement_count; m++) { + pstr_enc_loudness_info_set->str_loudness_info[n].str_loudness_measure[m].method_definition = + impd_drc_get_integer_value(fp); + pstr_enc_loudness_info_set->str_loudness_info[n].str_loudness_measure[m].method_value = + impd_drc_get_float_value(fp); + pstr_enc_loudness_info_set->str_loudness_info[n] + .str_loudness_measure[m] + .measurement_system = impd_drc_get_integer_value(fp); + pstr_enc_loudness_info_set->str_loudness_info[n].str_loudness_measure[m].reliability = + impd_drc_get_integer_value(fp); + } + } + + pstr_enc_loudness_info_set->loudness_info_album_count = impd_drc_get_integer_value(fp); + for (n = 0; n < pstr_enc_loudness_info_set->loudness_info_album_count; n++) { + pstr_enc_loudness_info_set->str_loudness_info_album[n].drc_set_id = + impd_drc_get_integer_value(fp); + pstr_enc_loudness_info_set->str_loudness_info_album[n].downmix_id = + impd_drc_get_integer_value(fp); + pstr_enc_loudness_info_set->str_loudness_info_album[n].sample_peak_level_present = + impd_drc_get_integer_value(fp); + if (1 == pstr_enc_loudness_info_set->str_loudness_info_album[n].sample_peak_level_present) { + pstr_enc_loudness_info_set->str_loudness_info_album[n].sample_peak_level = + impd_drc_get_float_value(fp); + } + pstr_enc_loudness_info_set->str_loudness_info_album[n].true_peak_level_present = + impd_drc_get_integer_value(fp); + if (1 == pstr_enc_loudness_info_set->str_loudness_info_album[n].true_peak_level_present) { + pstr_enc_loudness_info_set->str_loudness_info_album[n].true_peak_level = + impd_drc_get_float_value(fp); + pstr_enc_loudness_info_set->str_loudness_info_album[n].true_peak_level_measurement_system = + impd_drc_get_integer_value(fp); + pstr_enc_loudness_info_set->str_loudness_info_album[n].true_peak_level_reliability = + impd_drc_get_integer_value(fp); + } + pstr_enc_loudness_info_set->str_loudness_info_album[n].measurement_count = + impd_drc_get_integer_value(fp); + + for (m = 0; m < pstr_enc_loudness_info_set->str_loudness_info_album[n].measurement_count; + m++) { + pstr_enc_loudness_info_set->str_loudness_info_album[n] + .str_loudness_measure[m] + .method_definition = impd_drc_get_integer_value(fp); /* 0 = program loudness */ + pstr_enc_loudness_info_set->str_loudness_info_album[n] + .str_loudness_measure[m] + .method_value = impd_drc_get_float_value(fp); + pstr_enc_loudness_info_set->str_loudness_info_album[n] + .str_loudness_measure[m] + .measurement_system = impd_drc_get_integer_value(fp); /* 2 = ITU-R BS.1770-3 */ + pstr_enc_loudness_info_set->str_loudness_info_album[n].str_loudness_measure[m].reliability = + impd_drc_get_integer_value(fp); /* 0 = unknown */ + } + } + + /*********** str_channel_layout *************/ + + pstr_uni_drc_config->str_channel_layout.layout_signaling_present = 0; + pstr_uni_drc_config->str_channel_layout.defined_layout = 0; + pstr_uni_drc_config->str_channel_layout.speaker_position[0] = 0; + + /*********** str_downmix_instructions *************/ + + pstr_uni_drc_config->downmix_instructions_count = + 0; // pstr_ext_cfg_downmix_input->downmix_id_count; + for (n = 0; n < pstr_uni_drc_config->downmix_instructions_count; n++) { + pstr_uni_drc_config->str_downmix_instructions[n].target_layout = + impd_drc_get_integer_value(fp); + pstr_uni_drc_config->str_downmix_instructions[n].downmix_coefficients_present = + impd_drc_get_integer_value(fp); + } + + pstr_uni_drc_config->drc_description_basic_present = 0; + pstr_uni_drc_config->uni_drc_config_ext_present = 0; + pstr_enc_loudness_info_set->loudness_info_set_ext_present = 0; + pstr_enc_gain_extension->uni_drc_gain_ext_present = 0; +} diff --git a/test/encoder/impd_drc_user_config.h b/test/encoder/impd_drc_user_config.h new file mode 100644 index 0000000..5329460 --- /dev/null +++ b/test/encoder/impd_drc_user_config.h @@ -0,0 +1,25 @@ +/****************************************************************************** + * * + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ***************************************************************************** + * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore + */ + +#pragma once +VOID ixheaace_read_drc_config_params(FILE *fp, ia_drc_enc_params_struct *pstr_enc_params, + ia_drc_uni_drc_config_struct *pstr_uni_drc_config, + ia_drc_loudness_info_set_struct *pstr_enc_loudness_info_set, + ia_drc_uni_drc_gain_ext_struct *pstr_enc_gain_extension); diff --git a/test/encoder/ixheaace_error.c b/test/encoder/ixheaace_error.c index 5a7dc65..daa864f 100644 --- a/test/encoder/ixheaace_error.c +++ b/test/encoder/ixheaace_error.c @@ -48,6 +48,9 @@ pWORD8 ppb_ia_enhaacplus_enc_config_non_fatal[IA_MAX_ERROR_SUB_CODE] = { pWORD8 ppb_ia_enhaacplus_enc_mps_config_non_fatal[IA_MAX_ERROR_SUB_CODE] = { (pWORD8) "Invalid configuration", (pWORD8) "Invalid Parameter"}; +pWORD8 ppb_ia_enhaacplus_enc_drc_config_non_fatal[IA_MAX_ERROR_SUB_CODE] = { + (pWORD8) "Missing configuration"}; + /* Fatal Errors */ pWORD8 ppb_ia_enhaacplus_enc_config_fatal[IA_MAX_ERROR_SUB_CODE] = { (pWORD8) "Invalid sampling frequency of the stream", @@ -64,6 +67,16 @@ pWORD8 ppb_ia_enhaacplus_enc_config_fatal[IA_MAX_ERROR_SUB_CODE] = { (pWORD8) "Invalid speech configuration flag, use 0 or 1", }; +pWORD8 ppb_ia_enhaacplus_enc_usac_config_fatal[IA_MAX_ERROR_SUB_CODE] = { + (pWORD8) "Invalid sampling frequency", (pWORD8) "Invalid resampler ratio"}; + +pWORD8 ppb_ia_enhaacplus_enc_drc_config_fatal[IA_MAX_ERROR_SUB_CODE] = { + (pWORD8) "Invalid configuration", + (pWORD8) "Unsupported configuration", + (pWORD8) "Parameter out of range", + (pWORD8) "Compand failure", +}; + /*****************************************************************************/ /* Class 2: Initialization Errors *****************************************************************************/ @@ -90,6 +103,9 @@ pWORD8 ppb_ia_enhaacplus_enc_init_fatal[IA_MAX_ERROR_SUB_CODE] = { pWORD8 ppb_ia_enhaacplus_enc_mps_init_fatal[IA_MAX_ERROR_SUB_CODE] = { (pWORD8) "MPS Initialization failed"}; +pWORD8 ppb_ia_enhaacplus_enc_usac_init_fatal[IA_MAX_ERROR_SUB_CODE] = { + (pWORD8) "Resampler initialization failed", (pWORD8) "Insufficient bit-reservoir size"}; + pWORD8 ppb_ia_enhaacplus_enc_sbr_init_fatal[IA_MAX_ERROR_SUB_CODE] = { (pWORD8) "Invalid number of channels", (pWORD8) "Invalid sample rate mode", (pWORD8) "Invalid frequency coefficients", (pWORD8) "Invalid number of bands", @@ -149,6 +165,14 @@ pWORD8 ppb_ia_enhaacplus_enc_mps_exe_fatal[IA_MAX_ERROR_SUB_CODE] = { (pWORD8) "Invalid number of PCB levels", (pWORD8) "Error in complex FFT processing"}; +pWORD8 ppb_ia_enhaacplus_enc_usac_exe_fatal[IA_MAX_ERROR_SUB_CODE] = { + (pWORD8) "Invalid FAC length", + (pWORD8) "Invalid number of SBK", + (pWORD8) "Invalid number of channels", + (pWORD8) "Invalid bit reservoir level", + (pWORD8) "Invalid mapping", +}; + /*****************************************************************************/ /* error info structure */ /*****************************************************************************/ @@ -198,14 +222,22 @@ VOID ia_enhaacplus_enc_error_handler_init() { ppb_ia_enhaacplus_enc_config_non_fatal; ia_enhaacplus_enc_error_info.ppppb_error_msg_pointers[0][1][1] = ppb_ia_enhaacplus_enc_mps_config_non_fatal; + ia_enhaacplus_enc_error_info.ppppb_error_msg_pointers[0][1][2] = + ppb_ia_enhaacplus_enc_drc_config_non_fatal; ia_enhaacplus_enc_error_info.ppppb_error_msg_pointers[1][1][0] = ppb_ia_enhaacplus_enc_config_fatal; + ia_enhaacplus_enc_error_info.ppppb_error_msg_pointers[1][1][2] = + ppb_ia_enhaacplus_enc_usac_config_fatal; + ia_enhaacplus_enc_error_info.ppppb_error_msg_pointers[1][1][3] = + ppb_ia_enhaacplus_enc_drc_config_fatal; ia_enhaacplus_enc_error_info.ppppb_error_msg_pointers[0][2][1] = ppb_ia_enhaacplus_enc_mps_init_non_fatal; ia_enhaacplus_enc_error_info.ppppb_error_msg_pointers[1][2][0] = ppb_ia_enhaacplus_enc_init_fatal; ia_enhaacplus_enc_error_info.ppppb_error_msg_pointers[1][2][1] = ppb_ia_enhaacplus_enc_mps_init_fatal; + ia_enhaacplus_enc_error_info.ppppb_error_msg_pointers[1][2][2] = + ppb_ia_enhaacplus_enc_usac_init_fatal; ia_enhaacplus_enc_error_info.ppppb_error_msg_pointers[1][2][4] = ppb_ia_enhaacplus_enc_sbr_init_fatal; ia_enhaacplus_enc_error_info.ppppb_error_msg_pointers[0][3][1] = @@ -216,6 +248,8 @@ VOID ia_enhaacplus_enc_error_handler_init() { ppb_ia_enhaacplus_enc_exe_fatal; ia_enhaacplus_enc_error_info.ppppb_error_msg_pointers[1][3][1] = ppb_ia_enhaacplus_enc_mps_exe_fatal; + ia_enhaacplus_enc_error_info.ppppb_error_msg_pointers[1][3][2] = + ppb_ia_enhaacplus_enc_usac_exe_fatal; } IA_ERRORCODE ia_error_handler(ia_error_info_struct *p_mod_err_info, WORD8 *pb_context, diff --git a/test/encoder/ixheaace_testbench.c b/test/encoder/ixheaace_testbench.c index 8f3efd9..19d6976 100644 --- a/test/encoder/ixheaace_testbench.c +++ b/test/encoder/ixheaace_testbench.c @@ -24,6 +24,12 @@ #include #include #include "ixheaac_type_def.h" +#include "impd_drc_common_enc.h" +#include "impd_drc_uni_drc.h" +#include "impd_drc_tables.h" +#include "impd_drc_api.h" +#include "impd_drc_user_config.h" +#include "iusace_cnst.h" #include "ixheaace_api.h" #include "ixheaac_error_standards.h" #include "ixheaace_error_handler.h" @@ -56,12 +62,10 @@ extern ia_error_info_struct ia_enhaacplus_enc_error_info; /* Error codes for the testbench */ /*****************************************************************************/ #define IA_TESTBENCH_MFMAN_FATAL_FILE_OPEN_FAILED 0xFFFFA001 - +#define DRC_CONFIG_FILE "impd_drc_config_params.txt" /*****************************************************************************/ /* Global variables */ /*****************************************************************************/ -pVOID g_pv_arr_alloc_memory[MAX_MEM_ALLOCS]; -WORD g_w_malloc_count; FILE *g_pf_inp, *g_pf_out; FILE *g_drc_inp = NULL; FILE *g_pf_meta; @@ -87,7 +91,7 @@ IA_ERRORCODE ia_enhaacplus_enc_wav_header_decode(FILE *in_file, UWORD32 *n_chann WORD16 output_format; WORD32 check, count = 0; FLAG wav_format_pcm = 0, wav_format_extensible = 0; - UWORD16 cbSize = 0; + UWORD16 cb_size = 0; WORD32 curr_pos, size; *i_channel_mask = 0; @@ -125,13 +129,14 @@ IA_ERRORCODE ia_enhaacplus_enc_wav_header_decode(FILE *in_file, UWORD32 *n_chann data_start[2] = wav_hdr[38]; data_start[3] = wav_hdr[39]; } else if (wav_format_extensible) { - cbSize |= ((UWORD8)wav_hdr[37] << 8); - cbSize |= ((UWORD8)wav_hdr[36]); + cb_size |= ((UWORD8)wav_hdr[37] << 8); + cb_size |= ((UWORD8)wav_hdr[36]); - if (fread(&(wav_hdr[40]), 1, (UWORD16)(cbSize - 2 + 4), in_file) != (UWORD16)(cbSize - 2 + 4)) + if (fread(&(wav_hdr[40]), 1, (UWORD16)(cb_size - 2 + 4), in_file) != + (UWORD16)(cb_size - 2 + 4)) return 1; - if (cbSize > 34) { + if (cb_size > 34) { return 1; } @@ -141,10 +146,10 @@ IA_ERRORCODE ia_enhaacplus_enc_wav_header_decode(FILE *in_file, UWORD32 *n_chann *i_channel_mask |= (UWORD8)wav_hdr[41] << 8; *i_channel_mask |= (UWORD8)wav_hdr[40]; - data_start[0] = wav_hdr[40 + cbSize - 2 + 0]; - data_start[1] = wav_hdr[40 + cbSize - 2 + 1]; - data_start[2] = wav_hdr[40 + cbSize - 2 + 2]; - data_start[3] = wav_hdr[40 + cbSize - 2 + 3]; + data_start[0] = wav_hdr[40 + cb_size - 2 + 0]; + data_start[1] = wav_hdr[40 + cb_size - 2 + 1]; + data_start[2] = wav_hdr[40 + cb_size - 2 + 2]; + data_start[3] = wav_hdr[40 + cb_size - 2 + 3]; } check = 1; @@ -187,12 +192,21 @@ void ia_enhaacplus_enc_print_usage() { printf("\n[-mps:]"); printf("\n[-adts:]"); printf("\n[-tns:]"); + printf("\n[-nf:]"); + printf("\n[-cmpx_pred:]"); printf("\n[-framesize:]"); printf("\n[-aot:]"); printf("\n[-esbr:]"); - printf("\n[-full_bandwidth:]"); + printf("\n[-full_bandwidth:]"); printf("\n[-max_out_buffer_per_ch:]"); printf("\n[-tree_cfg:]"); + printf("\n[-usac:]"); + printf("\n[-ccfl_idx:]"); + printf("\n[-pvc_enc:]"); + printf("\n[-harmonic_sbr:]"); + printf("\n[-esbr_hq:]"); + printf("\n[-drc:]"); + printf("\n[-inter_tes_enc:]"); printf("\n\nwhere, \n is the parameter file with multiple commands"); printf("\n is the input 16-bit WAV or PCM file name"); printf("\n is the output ADTS/ES file name"); @@ -202,6 +216,10 @@ void ia_enhaacplus_enc_print_usage() { "\n Valid values are 0 ( No ADTS header) and 1 ( generate ADTS header). " "Default is 0."); printf("\n Valid values are 0 (disable TNS) and 1 (enable TNS). Default is 1."); + printf("\n controls usage of noise filling in encoding. Default 0."); + printf( + "\n controls usage of complex prediction in encoding. Default " + "0."); printf("\n is the framesize to be used."); printf( "\n For AOT 23, 39 (LD core coder profiles) valid values are 480 and 512. Default " @@ -211,19 +229,23 @@ void ia_enhaacplus_enc_print_usage() { "\n For AOT 2, 5, 29 (LC core coder profiles) valid values are 960 and 1024. " "Default " "is 1024."); + printf( + "\n For AOT 42 (USAC profile) valid values are 768 and 1024. " + "Default " + "is 1024."); printf("\n is the Audio object type"); printf("\n 2 for AAC-LC"); printf("\n 5 for HE-AACv1(Legacy SBR)"); printf("\n 23 for AAC-LD"); printf("\n 29 for HE-AACv2"); printf("\n 39 for AAC-ELD"); + printf("\n 42 for USAC"); printf("\n Default is 2 for AAC-LC."); + printf("\n Valid values are 0 (disable eSBR) and 1 (enable eSBR)."); + printf("\n Default is 0 for HE-AACv1 profile (legacy SBR) and 1 for USAC profile."); printf( - "\n Valid values are 0 (disable eSBR) and 1 (enable eSBR in HE-AACv1 " - "encoding). Default is 0."); - printf( - "\n Enable use of full bandwidth of input. Valid values are 0(disable " - "full bandwidth) and 1(enable full bandwidth). Default is 0."); + "\n Enable use of full bandwidth of input. Valid values are " + "0(disable full bandwidth) and 1(enable full bandwidth). Default is 0."); printf("\n is the maximum size of bit reservoir to be used."); printf( "\n Valid values are from -1 to 6144. -1 will omit use of bit reservoir. Default is " @@ -235,6 +257,30 @@ void ia_enhaacplus_enc_print_usage() { "\n 2 for '5152'" "\n 3 for '525'" "\n Default '212' for stereo input and '5151' for 6ch input."); + printf( + "\n USAC encoding mode to be chose" + "0 for 'usac_switched'" + "1 for 'usac_fd'" + "2 for 'usac_td'" + "Default 'usac_fd'"); + printf( + "\n is the core coder framelength index for USAC encoder"); + printf("\n Valid values are 0, 1, 2, 3, 4. eSBR enabling is implicit"); + printf("\n 0 - Core coder framelength of USAC is 768 and eSBR is disabled"); + printf("\n 1 - Core coder framelength of USAC is 1024 and eSBR is disabled"); + printf("\n 2 - Core coder framelength of USAC is 768 and eSBR ratio 8:3"); + printf("\n 3 - Core coder framelength of USAC is 1024 and eSBR ratio 2:1"); + printf("\n 4 - Core coder framelength of USAC is 1024 and eSBR ratio 4:1"); + printf("\n Valid values are 0 (disable PVC encoding) and " + "1 (enable PVC encoding). Default is 0."); + printf("\n Valid values are 0 (disable harmonic SBR) and " + "1 (enable harmonic SBR). Default is 0."); + printf("\n Valid values are 0 (disable high quality eSBR) and " + "1 (enable high quality eSBR). Default is 0."); + printf("\n Valid values are 0 (disable DRC encoding) and " + "1 (enable DRC encoding). Default is 0."); + printf("\n Valid values are 0 (disable inter - TES encoding) and " + "1 (enable inter - TES encoding). Default is 0.\n"); exit(1); } @@ -260,6 +306,16 @@ static VOID ixheaace_parse_config_param(WORD32 argc, pWORD8 argv[], pVOID ptr_en pstr_enc_api->input_config.aac_config.use_tns = atoi(pb_arg_val); pstr_enc_api->input_config.user_tns_flag = 1; } + /*noise filling*/ + if (!strncmp((pCHAR8)argv[i], "-nf:", 4)) { + pCHAR8 pb_arg_val = (pCHAR8)argv[i] + 4; + pstr_enc_api->input_config.aac_config.noise_filling = atoi(pb_arg_val); + } + /* Complex Prediction */ + if (!strncmp((pCHAR8)argv[i], "-cmpx_pred:", 11)) { + pCHAR8 pb_arg_val = (pCHAR8)(argv[i] + 11); + pstr_enc_api->input_config.cplx_pred = atoi(pb_arg_val); + } /*Use full bandwidth*/ if (!strncmp((const char *)argv[i], "-full_bandwidth:", 16)) { char *pb_arg_val = (char *)argv[i] + 16; @@ -278,6 +334,7 @@ static VOID ixheaace_parse_config_param(WORD32 argc, pWORD8 argv[], pVOID ptr_en if (!strncmp((const char *)argv[i], "-esbr:", 6)) { char *pb_arg_val = (char *)argv[i] + 6; pstr_enc_api->input_config.esbr_flag = atoi(pb_arg_val); + pstr_enc_api->input_config.user_esbr_flag = 1; } if (!strncmp((const char *)argv[i], "-max_out_buffer_per_ch:", 23)) { @@ -293,6 +350,37 @@ static VOID ixheaace_parse_config_param(WORD32 argc, pWORD8 argv[], pVOID ptr_en pCHAR8 pb_arg_val = (pCHAR8)(argv[i] + 6); pstr_enc_api->input_config.i_use_adts = atoi(pb_arg_val); } + if (!strncmp((const char *)argv[i], "-usac:", 6)) { + pCHAR8 pb_arg_val = (pCHAR8)(argv[i] + 6); + pstr_enc_api->input_config.codec_mode = atoi(pb_arg_val); + pstr_enc_api->input_config.usac_en = 1; + pstr_enc_api->input_config.aot = AOT_USAC; + } + if (!strncmp((const char *)argv[i], "-ccfl_idx:", 10)) { + pCHAR8 pb_arg_val = (pCHAR8)(argv[i] + 10); + pstr_enc_api->input_config.ccfl_idx = atoi(pb_arg_val); + } + if (!strncmp((const char *)argv[i], "-pvc_enc:", 9)) { + pCHAR8 pb_arg_val = (pCHAR8)(argv[i] + 9); + pstr_enc_api->input_config.pvc_active = atoi(pb_arg_val); + } + if (!strncmp((const char *)argv[i], "-harmonic_sbr:", 14)) { + pCHAR8 pb_arg_val = (pCHAR8)(argv[i] + 14); + pstr_enc_api->input_config.harmonic_sbr = atoi(pb_arg_val); + } + if (!strncmp((const char *)argv[i], "-esbr_hq:", 9)) { + pCHAR8 pb_arg_val = (pCHAR8)(argv[i] + 9); + pstr_enc_api->input_config.hq_esbr = atoi(pb_arg_val); + } + /* DRC */ + if (!strncmp((pCHAR8)argv[i], "-drc:", 5)) { + pCHAR8 pb_arg_val = (pCHAR8)(argv[i] + 5); + pstr_enc_api->input_config.use_drc_element = atoi(pb_arg_val); + } + if (!strncmp((const char *)argv[i], "-inter_tes_enc:", 15)) { + pCHAR8 pb_arg_val = (pCHAR8)(argv[i] + 15); + pstr_enc_api->input_config.inter_tes_active = atoi(pb_arg_val); + } } return; @@ -382,6 +470,11 @@ static VOID ixheaace_print_config_params(ixheaace_input_config *pstr_input_confi } } else if (pstr_input_config->aot == AOT_AAC_LD) { printf(" - AAC LD "); + } else if (pstr_input_config->aot == AOT_USAC) { + printf(" - USAC "); + if (pstr_input_config->i_use_mps == 1) { + printf(" MPS "); + } } else if (pstr_input_config->aot == AOT_PS) { printf(" - HEAACv2 "); } @@ -393,7 +486,77 @@ static VOID ixheaace_print_config_params(ixheaace_input_config *pstr_input_confi pstr_input_config->esbr_flag); } } + if (pstr_input_config->aot == AOT_USAC) { + if (pstr_input_config_user->codec_mode == pstr_input_config->codec_mode) { + printf("\nUSAC Codec Mode : "); + } else { + printf("\nUSAC Codec Mode (Invalid config value, setting to default) : "); + } + if (pstr_input_config->usac_en) { + if (pstr_input_config->codec_mode == USAC_SWITCHED) { + printf("Switched Mode"); + } else if (pstr_input_config->codec_mode == USAC_ONLY_FD) { + printf("FD Mode"); + } else if (pstr_input_config->codec_mode == USAC_ONLY_TD) { + printf("TD Mode"); + } + } else { + printf("Not Enabled"); + } + } + + if (pstr_input_config->aot == AOT_USAC) { + if (pstr_input_config_user->harmonic_sbr == pstr_input_config->harmonic_sbr) { + printf("\nHarmonic SBR : %d", pstr_input_config->harmonic_sbr); + } else { + printf("\nHarmonic SBR (Invalid config value, setting to default) : %d", + pstr_input_config->harmonic_sbr); + } + if (pstr_input_config_user->hq_esbr == pstr_input_config->hq_esbr) { + printf("\nHigh quality esbr : %d", pstr_input_config->hq_esbr); + } else { + printf("\nHigh quality esbr Flag (Invalid config value, setting to default) : %d", + pstr_input_config->hq_esbr); + } + if (pstr_input_config_user->cplx_pred == pstr_input_config->cplx_pred) { + printf("\nComplex Prediction Flag : %d", pstr_input_config->cplx_pred); + } else { + printf("\nComplex Prediction Flag (Invalid config value, setting to default) : %d", + pstr_input_config->cplx_pred); + } + if (pstr_input_config_user->aac_config.use_tns == pstr_input_config->aac_config.use_tns) { + printf("\nTNS Flag : %d", pstr_input_config->aac_config.use_tns); + } else { + printf("\nTNS Flag (Invalid config value, setting to default) : %d", + pstr_input_config->aac_config.use_tns); + } + + if (pstr_input_config_user->ccfl_idx == pstr_input_config->ccfl_idx) { + printf("\nCore-coder framelength index : %d", pstr_input_config->ccfl_idx); + } else { + if (pstr_input_config_user->ccfl_idx >= NO_SBR_CCFL_768 && + pstr_input_config_user->ccfl_idx <= SBR_4_1) { + if (pstr_input_config_user->ccfl_idx == NO_SBR_CCFL_768 && + pstr_input_config->ccfl_idx == SBR_8_3) { + printf( + "\nCore-coder framelength index (Unsupported configuration, enabling 8:3 eSBR) : " + "%d", + pstr_input_config->ccfl_idx); + } + if (pstr_input_config_user->ccfl_idx == NO_SBR_CCFL_1024 && + pstr_input_config->ccfl_idx == SBR_2_1) { + printf( + "\nCore-coder framelength index (Unsupported configuration, enabling 2:1 eSBR) : " + "%d", + pstr_input_config->ccfl_idx); + } + } else { + printf("\nCore-coder framelength index (Invalid config value, setting to default) : %d", + pstr_input_config->ccfl_idx); + } + } + } if (pstr_input_config_user->aac_config.noise_filling == pstr_input_config->aac_config.noise_filling) { printf("\nNoise Filling Flag : %d", pstr_input_config->aac_config.noise_filling); @@ -473,6 +636,12 @@ static VOID ixheaace_print_config_params(ixheaace_input_config *pstr_input_confi } else { printf("\nSampling Frequency : %d Hz", pstr_input_config_user->i_samp_freq); } + + if (pstr_input_config->aot == AOT_USAC && pstr_input_config->use_drc_element) { + printf("\nDRC : Enabled"); + printf("\nDRC Effects : "); + printf("Night, Noisy, Limited, Low level, Dialog, General, Expand, Artistic"); + } printf( "\n*************************************************************************************" "***********\n\n"); @@ -552,6 +721,7 @@ IA_ERRORCODE ia_enhaacplus_enc_main_process(WORD32 argc, pWORD8 argv[]) { pstr_in_cfg->i_bitrate = pstr_in_cfg->aac_config.bitrate; pstr_in_cfg->aot = AOT_AAC_LC; + pstr_in_cfg->codec_mode = USAC_ONLY_FD; pstr_in_cfg->i_channels = 2; pstr_in_cfg->i_samp_freq = 44100; pstr_in_cfg->i_use_mps = 0; @@ -559,7 +729,12 @@ IA_ERRORCODE ia_enhaacplus_enc_main_process(WORD32 argc, pWORD8 argv[]) { pstr_in_cfg->i_use_adts = 0; pstr_in_cfg->esbr_flag = 0; pstr_in_cfg->i_use_es = 1; - + pstr_in_cfg->cplx_pred = 0; + pstr_in_cfg->ccfl_idx = NO_SBR_CCFL_1024; + pstr_in_cfg->pvc_active = 0; + pstr_in_cfg->harmonic_sbr = 0; + pstr_in_cfg->inter_tes_active = 0; + pstr_in_cfg->use_drc_element = 0; pstr_in_cfg->i_channels_mask = 0; pstr_in_cfg->i_num_coupling_chan = 0; pstr_in_cfg->aac_config.full_bandwidth = 0; @@ -568,6 +743,7 @@ IA_ERRORCODE ia_enhaacplus_enc_main_process(WORD32 argc, pWORD8 argv[]) { pstr_in_cfg->frame_cmd_flag = 0; pstr_in_cfg->out_bytes_flag = 0; pstr_in_cfg->user_tns_flag = 0; + pstr_in_cfg->user_esbr_flag = 0; pstr_in_cfg->i_use_adts = !eld_ga_hdr; /* ******************************************************************/ /* Parse input configuration parameters */ @@ -594,6 +770,13 @@ IA_ERRORCODE ia_enhaacplus_enc_main_process(WORD32 argc, pWORD8 argv[]) { pstr_in_cfg->aac_config.bitreservoir_size = APP_BITRES_SIZE_CONFIG_PARAM_DEF_VALUE_LD; } + if (pstr_in_cfg->user_tns_flag == 0) { + pstr_in_cfg->aac_config.use_tns = 1; + } + } else if (pstr_in_cfg->aot == AOT_USAC) { + if (pstr_in_cfg->user_esbr_flag == 0) { + pstr_in_cfg->esbr_flag = 1; + } if (pstr_in_cfg->user_tns_flag == 0) { pstr_in_cfg->aac_config.use_tns = 1; } @@ -641,7 +824,56 @@ IA_ERRORCODE ia_enhaacplus_enc_main_process(WORD32 argc, pWORD8 argv[]) { /* ******************************************************************/ /* Initialize API structure and set config params to default */ /* ******************************************************************/ + /* DRC */ + if (pstr_in_cfg->use_drc_element == 1 && pstr_in_cfg->aot == AOT_USAC) { + LOOPIDX k; + CHAR8 drc_config_file_name[IA_MAX_CMD_LINE_LENGTH]; + strcpy(drc_config_file_name, DRC_CONFIG_FILE); + g_drc_inp = fopen(drc_config_file_name, "rt"); + if (!g_drc_inp) { + printf("\nError in opening DRC configuration file\n\n"); + pstr_in_cfg->use_drc_element = 0; + } + + if (g_drc_inp != 0) { + memset(&pstr_in_cfg->str_drc_cfg, 0, sizeof(ia_drc_input_config)); + ixheaace_read_drc_config_params(g_drc_inp, &pstr_in_cfg->str_drc_cfg.str_enc_params, + &pstr_in_cfg->str_drc_cfg.str_uni_drc_config, + &pstr_in_cfg->str_drc_cfg.str_enc_loudness_info_set, + &pstr_in_cfg->str_drc_cfg.str_enc_gain_extension); + + pstr_in_cfg->str_drc_cfg.str_enc_params.gain_sequence_present = FALSE; + for (k = 0; k < pstr_in_cfg->str_drc_cfg.str_uni_drc_config.drc_coefficients_uni_drc_count; + k++) { + if (pstr_in_cfg->str_drc_cfg.str_uni_drc_config.str_drc_coefficients_uni_drc[k] + .drc_location == 1) { + if (pstr_in_cfg->str_drc_cfg.str_uni_drc_config.str_drc_coefficients_uni_drc[k] + .gain_set_count > 0) { + pstr_in_cfg->str_drc_cfg.str_enc_params.gain_sequence_present = TRUE; + break; + } + } + } + + if (pstr_in_cfg->str_drc_cfg.str_enc_params.gain_sequence_present == FALSE) { + for (k = 0; k < pstr_in_cfg->str_drc_cfg.str_uni_drc_config.str_uni_drc_config_ext + .drc_coefficients_uni_drc_v1_count; + k++) { + if (pstr_in_cfg->str_drc_cfg.str_uni_drc_config.str_uni_drc_config_ext + .str_drc_coefficients_uni_drc_v1[k] + .drc_location == 1) { + if (pstr_in_cfg->str_drc_cfg.str_uni_drc_config.str_uni_drc_config_ext + .str_drc_coefficients_uni_drc_v1[k] + .gain_sequence_count > 0) { + pstr_in_cfg->str_drc_cfg.str_enc_params.gain_sequence_present = TRUE; + break; + } + } + } + } + } + } memcpy(pstr_in_cfg_user, pstr_in_cfg, sizeof(ixheaace_input_config)); err_code = ixheaace_create((pVOID)pstr_in_cfg, (pVOID)pstr_out_cfg); @@ -680,7 +912,7 @@ IA_ERRORCODE ia_enhaacplus_enc_main_process(WORD32 argc, pWORD8 argv[]) { { ia_enhaacplus_enc_fwrite(pb_out_buf, g_pf_out, 0); } - if (pstr_in_cfg->i_use_es) { + if ((pstr_in_cfg->usac_en || pstr_in_cfg->i_use_es)) { i_dec_len = pstr_out_cfg->i_out_bytes; ia_enhaacplus_enc_fwrite(pb_out_buf, g_pf_out, pstr_out_cfg->i_out_bytes); fflush(g_pf_out); @@ -713,7 +945,7 @@ IA_ERRORCODE ia_enhaacplus_enc_main_process(WORD32 argc, pWORD8 argv[]) { if (max_frame_size < i_out_bytes) max_frame_size = i_out_bytes; - if (pstr_in_cfg->i_use_es || !(pstr_in_cfg->i_use_adts)) { + if (pstr_in_cfg->usac_en || pstr_in_cfg->i_use_es || !(pstr_in_cfg->i_use_adts)) { if (i_out_bytes) ia_stsz_size[frame_count - 1] = i_out_bytes; else @@ -747,7 +979,7 @@ IA_ERRORCODE ia_enhaacplus_enc_main_process(WORD32 argc, pWORD8 argv[]) { return (err_code); } - if ((pstr_in_cfg->i_use_es) && (g_pf_meta)) { + if ((pstr_in_cfg->usac_en || pstr_in_cfg->i_use_es) && (g_pf_meta)) { fprintf(g_pf_meta, "-dec_info_init:%d\n", i_dec_len); fprintf(g_pf_meta, "-g_track_count:%d\n", 1); fprintf(g_pf_meta, "-ia_mp4_stsz_entries:%d\n", frame_count); @@ -773,7 +1005,7 @@ IA_ERRORCODE ia_enhaacplus_enc_main_process(WORD32 argc, pWORD8 argv[]) { int main(WORD32 argc, pCHAR8 argv[]) { FILE *param_file_id = NULL; - + WORD32 usac_en = 0; WORD8 curr_cmd[IA_MAX_CMD_LINE_LENGTH]; WORD32 fargc, curpos; WORD32 processcmd = 0; @@ -813,6 +1045,7 @@ int main(WORD32 argc, pCHAR8 argv[]) { WORD8 pb_meta_file_name[IA_MAX_CMD_LINE_LENGTH] = ""; curpos = 0; fargc = 0; + usac_en = 0; /* if it is not a param_file command and if */ /* CLP processing is not enabled */ if (curr_cmd[0] != '@' && !processcmd) { /* skip it */ @@ -905,7 +1138,9 @@ int main(WORD32 argc, pCHAR8 argv[]) { } file_count++; } - + if (!strncmp((const char *)fargv[i], "-usac:", 6)) { + usac_en = 1; + } if (!strncmp((const char *)fargv[i], "-aot:", 5)) { pWORD8 pb_arg_val = fargv[i] + 5; aot_value = atoi((const char *)(pb_arg_val)); @@ -919,7 +1154,6 @@ int main(WORD32 argc, pCHAR8 argv[]) { if ((atoi((const char *)pb_arg_val))) eld_ga_hdr = 0; } } - g_w_malloc_count = 0; printf("\n"); @@ -931,7 +1165,7 @@ int main(WORD32 argc, pCHAR8 argv[]) { eld_ga_hdr = 1; } - if ((strcmp((const char *)pb_output_file_name, "")) && (eld_ga_hdr)) { + if ((strcmp((const char *)pb_output_file_name, "")) && (usac_en || eld_ga_hdr)) { char *file_name = strrchr((const char *)pb_output_file_name, '.'); SIZE_T idx = file_name - (char *)pb_output_file_name; memcpy(pb_meta_file_name, pb_output_file_name, idx); @@ -997,6 +1231,9 @@ int main(WORD32 argc, pCHAR8 argv[]) { file_count++; } + if (!strncmp((const char *)argv[i], "-usac:", 6)) { + usac_en = 1; + } if (!strncmp((const char *)argv[i], "-aot:", 5)) { pCHAR8 pb_arg_val = argv[i] + 5; aot_value = atoi((const char *)(pb_arg_val)); @@ -1014,7 +1251,6 @@ int main(WORD32 argc, pCHAR8 argv[]) { ia_enhaacplus_enc_print_usage(); } } - g_w_malloc_count = 0; printf("\n"); if (file_count != 2) { @@ -1027,7 +1263,8 @@ int main(WORD32 argc, pCHAR8 argv[]) { #ifdef _WIN32 #pragma warning(suppress : 6001) #endif - if ((strcmp((const char *)pb_output_file_name, "")) && (eld_ga_hdr)) { + + if ((strcmp((const char *)pb_output_file_name, "")) && (usac_en || eld_ga_hdr)) { char *file_name = strrchr((const char *)pb_output_file_name, '.'); SIZE_T idx = file_name - (char *)pb_output_file_name; memcpy(pb_meta_file_name, pb_output_file_name, idx); diff --git a/test/encoder/paramfilesimple.txt b/test/encoder/paramfilesimple.txt index b4a6876..b3133f2 100644 --- a/test/encoder/paramfilesimple.txt +++ b/test/encoder/paramfilesimple.txt @@ -20,4 +20,9 @@ //ELDv2 -ifile:sine_2ch.wav -ofile:sine_2ch_aot_39_mps.es -br:64000 -aot:39 -mps:1 +//USAC +-ifile:sine_2ch.wav -ofile:sine_2ch_aot_42.es -br:64000 -aot:42 + +//DRC +-ifile:sine_2ch.wav -ofile:sine_2ch_aot_42_drc.es -br:64000 -usac:1 -drc:1 @Stop \ No newline at end of file diff --git a/test/encoder/xaacenc.cmake b/test/encoder/xaacenc.cmake index a81115c..713d357 100644 --- a/test/encoder/xaacenc.cmake +++ b/test/encoder/xaacenc.cmake @@ -1,10 +1,12 @@ list(APPEND XAACENC_SRCS + "${XAAC_ROOT}/test/encoder/impd_drc_user_config.c" "${XAAC_ROOT}/test/encoder/ixheaace_error.c" "${XAAC_ROOT}/test/encoder/ixheaace_testbench.c" "${XAAC_ROOT}/test/encoder/ixheaace_wav_reader.c") set(LIBXAACENC_INCLUDES ${XAAC_ROOT}/encoder ${XAAC_ROOT}/test/encoder + ${XAAC_ROOT}/encoder/drc_src ${XAAC_ROOT}/common) include_directories(${LIBXAACENC_INCLUDES})