From 797de4d1e90e8bcfc19fdae6923a116d761ba0d5 Mon Sep 17 00:00:00 2001 From: Nikhil Bhavikatti <97579291+nikhil-bhavikatti@users.noreply.github.com> Date: Fri, 14 Jul 2023 13:04:15 +0530 Subject: [PATCH] USAC along with DRC support for libxaac encoder (#37) --- Android.bp | 48 + CMakeLists.txt | 1 + README.md | 7 +- README_enc.md | 71 +- decoder/drc_src/impd_drc_tables.h | 43 - docs/LIBXAAC-Enc-API.pdf | Bin 435709 -> 770248 bytes docs/LIBXAAC-Enc-GSG.pdf | Bin 329556 -> 344933 bytes encoder/drc_src/impd_drc_api.c | 210 + encoder/drc_src/impd_drc_api.h | 43 + encoder/drc_src/impd_drc_common_enc.h | 79 + encoder/drc_src/impd_drc_enc.c | 284 + encoder/drc_src/impd_drc_enc.h | 40 + encoder/drc_src/impd_drc_gain_calculator.c | 518 ++ encoder/drc_src/impd_drc_gain_enc.c | 1003 +++ encoder/drc_src/impd_drc_gain_enc.h | 211 + encoder/drc_src/impd_drc_mux.c | 3200 ++++++++ .../impd_drc_mux.h} | 23 +- encoder/drc_src/impd_drc_struct_def.h | 51 + encoder/drc_src/impd_drc_tables.c | 214 + encoder/drc_src/impd_drc_tables.h | 62 + encoder/drc_src/impd_drc_uni_drc.h | 599 ++ encoder/drc_src/impd_drc_uni_drc_eq.c | 1439 ++++ encoder/drc_src/impd_drc_uni_drc_eq.h | 172 + .../drc_src/impd_drc_uni_drc_filter_bank.c | 184 + .../drc_src/impd_drc_uni_drc_filter_bank.h | 39 + encoder/drc_src/libxaacenc_drc.cmake | 12 + encoder/iusace_acelp_enc.c | 439 ++ encoder/iusace_acelp_rom.c | 213 + encoder/iusace_acelp_tools.c | 1082 +++ encoder/iusace_arith_enc.c | 433 ++ encoder/iusace_arith_enc.h | 47 + encoder/iusace_avq_enc.c | 343 + encoder/iusace_avq_enc.h | 38 + encoder/iusace_avq_rom.c | 674 ++ encoder/iusace_block_switch.c | 282 + encoder/iusace_block_switch.h | 27 + encoder/iusace_block_switch_const.h | 45 + encoder/iusace_block_switch_struct_def.h | 39 + encoder/iusace_cnst.h | 1 + encoder/iusace_config.h | 203 + encoder/iusace_enc_fac.c | 534 ++ encoder/iusace_enc_main.c | 1333 ++++ encoder/iusace_esbr_inter_tes.c | 793 ++ encoder/iusace_esbr_inter_tes.h | 115 + encoder/iusace_esbr_pvc.c | 426 + encoder/iusace_esbr_pvc.h | 131 + encoder/iusace_esbr_pvc_rom.c | 251 + encoder/iusace_esbr_rom.c | 32 + encoder/iusace_esbr_rom.h | 24 + encoder/iusace_fd_enc.h | 26 + encoder/iusace_fd_fac.c | 328 + encoder/iusace_fd_qc_adjthr.h | 104 + encoder/iusace_fd_qc_util.h | 74 + encoder/iusace_fd_quant.h | 35 + encoder/iusace_fft.c | 741 ++ encoder/iusace_fft.h | 5 + encoder/iusace_func_prototypes.h | 81 + encoder/iusace_lpc.c | 216 + encoder/iusace_lpc_avq.c | 372 + encoder/iusace_lpd.h | 67 + encoder/iusace_lpd_enc.c | 818 ++ encoder/iusace_lpd_rom.c | 417 + encoder/iusace_lpd_rom.h | 39 + encoder/iusace_lpd_utils.c | 593 ++ encoder/iusace_main.h | 125 + encoder/iusace_ms.c | 142 + encoder/iusace_ms.h | 35 + encoder/iusace_psy_mod.c | 275 + encoder/iusace_psy_mod.h | 150 + encoder/iusace_psy_rom.c | 218 + encoder/iusace_psy_utils.c | 550 ++ encoder/iusace_psy_utils.h | 45 + encoder/iusace_rom.c | 6863 ++++++++++++++++- encoder/iusace_rom.h | 102 +- encoder/iusace_signal_classifier.h | 152 + encoder/iusace_tcx_enc.c | 844 ++ encoder/iusace_tcx_mdct.c | 186 + encoder/iusace_tcx_mdct.h | 29 + encoder/iusace_tns_usac.c | 533 ++ encoder/iusace_tns_usac.h | 88 + encoder/iusace_windowing.c | 180 + encoder/iusace_windowing.h | 34 + encoder/iusace_write_bitstream.c | 740 ++ encoder/iusace_write_bitstream.h | 62 + encoder/ixheaace_aac_constants.h | 5 +- encoder/ixheaace_adjust_threshold.c | 4 + encoder/ixheaace_api.c | 1481 +++- encoder/ixheaace_api.h | 12 + encoder/ixheaace_api_defs.h | 7 + encoder/ixheaace_asc_write.c | 332 +- encoder/ixheaace_asc_write.h | 4 +- encoder/ixheaace_bits_count.c | 4 + encoder/ixheaace_block_switch.c | 1 + encoder/ixheaace_channel_map.c | 6 +- encoder/ixheaace_common_utils.h | 2 + encoder/ixheaace_config_params.h | 2 +- encoder/ixheaace_cplx_pred.c | 522 ++ encoder/ixheaace_cplx_pred.h | 26 + encoder/ixheaace_dynamic_bits.c | 8 +- encoder/ixheaace_enc_init.c | 4 + encoder/ixheaace_enc_main.c | 7 +- encoder/ixheaace_error_codes.h | 34 +- encoder/ixheaace_fd_enc.c | 133 + encoder/ixheaace_fd_mdct.c | 214 + encoder/ixheaace_fd_qc_adjthr.c | 1698 ++++ encoder/ixheaace_fd_qc_util.c | 164 + encoder/ixheaace_fd_quant.c | 672 ++ encoder/ixheaace_hybrid.c | 8 +- encoder/ixheaace_memory_standards.h | 1 + encoder/ixheaace_mps_bitstream.c | 4 + encoder/ixheaace_mps_dct.c | 4 +- encoder/ixheaace_mps_enc.c | 7 +- encoder/ixheaace_mps_frame_windowing.c | 2 +- encoder/ixheaace_mps_nlc_enc.c | 16 +- encoder/ixheaace_mps_param_extract.c | 4 + encoder/ixheaace_mps_tools_rom.c | 4 + encoder/ixheaace_nf.c | 165 + encoder/ixheaace_nf.h | 26 + encoder/ixheaace_psy_configuration.c | 4 + encoder/ixheaace_psy_mod.c | 4 + encoder/ixheaace_qc_util.c | 5 +- encoder/ixheaace_quant.c | 2 +- encoder/ixheaace_resampler.h | 4 + encoder/ixheaace_resampler_init.c | 29 + encoder/ixheaace_sbr.h | 3 + encoder/ixheaace_sbr_code_envelope.c | 4 +- encoder/ixheaace_sbr_code_envelope_lp.c | 8 +- encoder/ixheaace_sbr_enc_struct.h | 18 +- encoder/ixheaace_sbr_env_est.c | 1096 ++- encoder/ixheaace_sbr_env_est.h | 3 +- encoder/ixheaace_sbr_env_est_init.c | 21 +- encoder/ixheaace_sbr_freq_scaling.c | 181 +- encoder/ixheaace_sbr_freq_scaling.h | 3 +- encoder/ixheaace_sbr_hbe.h | 176 + encoder/ixheaace_sbr_hbe_dft_trans.c | 945 +++ encoder/ixheaace_sbr_hbe_fft.h | 35 +- encoder/ixheaace_sbr_hbe_fft_ifft_32x32.c | 1679 ++++ encoder/ixheaace_sbr_hbe_polyphase.c | 329 + encoder/ixheaace_sbr_hbe_trans.c | 1499 ++++ encoder/ixheaace_sbr_header.h | 4 + encoder/ixheaace_sbr_main.c | 196 +- encoder/ixheaace_sbr_main.h | 18 +- encoder/ixheaace_sbr_missing_harmonics_det.c | 2 + encoder/ixheaace_sbr_noise_floor_est.c | 8 +- encoder/ixheaace_sbr_qmf_enc.c | 28 +- encoder/ixheaace_sbr_qmf_enc.h | 9 +- encoder/ixheaace_sbr_rom.c | 448 ++ encoder/ixheaace_sbr_ton_corr.c | 3 +- encoder/ixheaace_sbr_ton_corr_hp.c | 2 + encoder/ixheaace_sbr_tran_det.c | 11 +- encoder/ixheaace_sbr_tran_det.h | 3 +- encoder/ixheaace_sbr_write_bitstream.c | 349 +- encoder/ixheaace_sf_estimation.c | 14 +- encoder/ixheaace_signal_classifier.c | 1077 +++ encoder/ixheaace_signal_classifier_rom.c | 1518 ++++ encoder/ixheaace_static_bits.c | 4 + encoder/ixheaace_struct_def.h | 7 + encoder/ixheaace_tns.c | 4 - encoder/ixheaace_tns_hp.c | 9 +- encoder/ixheaace_tns_params.c | 4 + encoder/ixheaace_write_adts_adif.c | 7 +- encoder/ixheaace_write_bitstream.c | 28 +- encoder/libxaacenc.cmake | 45 +- fuzzer/xaac_enc_fuzzer.cmake | 2 +- fuzzer/xaac_enc_fuzzer.cpp | 365 +- test/Android.bp | 3 +- test/encoder/impd_drc_config_params.txt | 232 + test/encoder/impd_drc_user_config.c | 315 + test/encoder/impd_drc_user_config.h | 25 + test/encoder/ixheaace_error.c | 34 + test/encoder/ixheaace_testbench.c | 293 +- test/encoder/paramfilesimple.txt | 5 + test/encoder/xaacenc.cmake | 2 + 173 files changed, 47678 insertions(+), 354 deletions(-) delete mode 100644 decoder/drc_src/impd_drc_tables.h create mode 100644 encoder/drc_src/impd_drc_api.c create mode 100644 encoder/drc_src/impd_drc_api.h create mode 100644 encoder/drc_src/impd_drc_common_enc.h create mode 100644 encoder/drc_src/impd_drc_enc.c create mode 100644 encoder/drc_src/impd_drc_enc.h create mode 100644 encoder/drc_src/impd_drc_gain_calculator.c create mode 100644 encoder/drc_src/impd_drc_gain_enc.c create mode 100644 encoder/drc_src/impd_drc_gain_enc.h create mode 100644 encoder/drc_src/impd_drc_mux.c rename encoder/{ixheaace_sbr_hbe_fft_ifft_rom.h => drc_src/impd_drc_mux.h} (62%) create mode 100644 encoder/drc_src/impd_drc_struct_def.h create mode 100644 encoder/drc_src/impd_drc_tables.c create mode 100644 encoder/drc_src/impd_drc_tables.h create mode 100644 encoder/drc_src/impd_drc_uni_drc.h create mode 100644 encoder/drc_src/impd_drc_uni_drc_eq.c create mode 100644 encoder/drc_src/impd_drc_uni_drc_eq.h create mode 100644 encoder/drc_src/impd_drc_uni_drc_filter_bank.c create mode 100644 encoder/drc_src/impd_drc_uni_drc_filter_bank.h create mode 100644 encoder/drc_src/libxaacenc_drc.cmake create mode 100644 encoder/iusace_acelp_enc.c create mode 100644 encoder/iusace_acelp_rom.c create mode 100644 encoder/iusace_acelp_tools.c create mode 100644 encoder/iusace_arith_enc.c create mode 100644 encoder/iusace_arith_enc.h create mode 100644 encoder/iusace_avq_enc.c create mode 100644 encoder/iusace_avq_enc.h create mode 100644 encoder/iusace_avq_rom.c create mode 100644 encoder/iusace_block_switch.c create mode 100644 encoder/iusace_block_switch.h create mode 100644 encoder/iusace_block_switch_const.h create mode 100644 encoder/iusace_block_switch_struct_def.h create mode 100644 encoder/iusace_enc_fac.c create mode 100644 encoder/iusace_enc_main.c create mode 100644 encoder/iusace_esbr_inter_tes.c create mode 100644 encoder/iusace_esbr_inter_tes.h create mode 100644 encoder/iusace_esbr_pvc.c create mode 100644 encoder/iusace_esbr_pvc.h create mode 100644 encoder/iusace_esbr_pvc_rom.c create mode 100644 encoder/iusace_esbr_rom.c create mode 100644 encoder/iusace_esbr_rom.h create mode 100644 encoder/iusace_fd_enc.h create mode 100644 encoder/iusace_fd_fac.c create mode 100644 encoder/iusace_fd_qc_adjthr.h create mode 100644 encoder/iusace_fd_qc_util.h create mode 100644 encoder/iusace_fd_quant.h create mode 100644 encoder/iusace_func_prototypes.h create mode 100644 encoder/iusace_lpc.c create mode 100644 encoder/iusace_lpc_avq.c create mode 100644 encoder/iusace_lpd.h create mode 100644 encoder/iusace_lpd_enc.c create mode 100644 encoder/iusace_lpd_rom.c create mode 100644 encoder/iusace_lpd_rom.h create mode 100644 encoder/iusace_lpd_utils.c create mode 100644 encoder/iusace_main.h create mode 100644 encoder/iusace_ms.c create mode 100644 encoder/iusace_ms.h create mode 100644 encoder/iusace_psy_mod.c create mode 100644 encoder/iusace_psy_mod.h create mode 100644 encoder/iusace_psy_rom.c create mode 100644 encoder/iusace_psy_utils.c create mode 100644 encoder/iusace_psy_utils.h create mode 100644 encoder/iusace_signal_classifier.h create mode 100644 encoder/iusace_tcx_enc.c create mode 100644 encoder/iusace_tcx_mdct.c create mode 100644 encoder/iusace_tcx_mdct.h create mode 100644 encoder/iusace_tns_usac.c create mode 100644 encoder/iusace_tns_usac.h create mode 100644 encoder/iusace_windowing.c create mode 100644 encoder/iusace_windowing.h create mode 100644 encoder/iusace_write_bitstream.c create mode 100644 encoder/iusace_write_bitstream.h create mode 100644 encoder/ixheaace_cplx_pred.c create mode 100644 encoder/ixheaace_cplx_pred.h create mode 100644 encoder/ixheaace_fd_enc.c create mode 100644 encoder/ixheaace_fd_mdct.c create mode 100644 encoder/ixheaace_fd_qc_adjthr.c create mode 100644 encoder/ixheaace_fd_qc_util.c create mode 100644 encoder/ixheaace_fd_quant.c create mode 100644 encoder/ixheaace_nf.c create mode 100644 encoder/ixheaace_nf.h create mode 100644 encoder/ixheaace_sbr_hbe_fft_ifft_32x32.c create mode 100644 encoder/ixheaace_sbr_hbe_polyphase.c create mode 100644 encoder/ixheaace_signal_classifier.c create mode 100644 encoder/ixheaace_signal_classifier_rom.c create mode 100644 test/encoder/impd_drc_config_params.txt create mode 100644 test/encoder/impd_drc_user_config.c create mode 100644 test/encoder/impd_drc_user_config.h 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 cd09eac05e597d6a0fdd628811252978f618fcc1..e915e461c3b54d2a2d893bd00652768ec9a36a23 100644 GIT binary patch delta 659258 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 z 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

nQBt^M>m`!4X2Sm2%{wdp$C1f2(dOuP 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

UVzwOqt*J`XPE{LB$5n*$OvhNo;#?pt?` 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

LWgPbhg{Cb9q6J2{APS4X@A8~| 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²Yw5j0GtR+1x^A^27U*e0-Oq*2AmF@0h|e(1)L3> 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�$S@8N8AiSiFB}fV5E(kab8X*oDMKZAssaXu z|CLLLPytQh3(cm4n+_lGP zxdPhe&+5lC)gRqF*ru1O4I{lu`r5&LO3D^FkXL8lqJUbq{~2C@852 zs)%AF1eK&Q%3r#JZ|}~?$<aW_cWn2+2I0H3&fYsx+q|EuQbZw+l5*23uz*q@`h1dj_A-CjwH>v{amNnHS^2o-^Naf(pIX*tm7Z(%tatfJwJJjm;C(tg@E=G%v2}mh$qWF6^qCi$tC1 zd^&B($|?X~6uw*1B;I_LyF_qS=2XUsMYV)9RpCrz5+l3n4i-Tp5g?)`{yI(N7emVq zjtKKM`wG3tnS-FPnBjkoSA^o1=+s8+*8;zHp*9DOMqnmeaFI>f0qmWMc+Si_D>QT$e+Qt9%8b1rBA6a7jIqU`@-HA6{Zk+=2F$YFr>Rj z!=0&|7Ws0=7>-5AiH_A~wE=rygDfn9;qmKlnl~sb#e;uY`N%nnd#m&pc#TVE z)n2qGZf-{VT2sZYxHlb4c`(?MWTAYOX?&T69>2CuCByM32BF?%{Pv7G!{A7S%^#6o zE_-uxrY;#?G$}XVd+8))VL*0YONx$p@u)`Rkc3=qjM_%YEmtwGjt_IMf&%foJ{%Pu zP+NVw)-9Aeu+)E8O{Z^AYB44+{OYD4`Z^D4Eni)4^X_1Yj$mVre?mXM%91{>5JoT2 zmL=5mIMo?N8gGP~d4`?tre*2$+FWOw3kcsHpzxV}fp2mG-$(d{{RhA|sC=Rl;^JT6 z8!U=#6@RlV|D96hp{T2T=_3xHU%qF&w7eGV6z767qU(RnqJR)X*5?8pwFE4i8m6%I zJ{5o1^B-AYGUP>Ib}6v4#iKgN8P5k|0ka!`GVN=turo$VRQ)=)q>wiipTrjQc>$(- ziC0yqA3k4JBed7-u@X6KrMh@nEmY(TCl2cnZAmb?(HW~9Q`eY%tP9KNwy&A(T`0bC z6#HJaju(Hm$AQ6OuY-LBNTPy4Z3JkNdIsMUbe4=UsOId z|4?hgZ7QklM(*NCJ_^jjkS=L-c^FdsnIA{-Y+}32jIi>ZoTbOM)tS&bGN+zCYug3pdN1?OOPXY zz-2FAP2cT)^F{W9Wz5}9lJUF`Yo@NOz|Hz5`&Q@C<(UP)>U+7VJQMG#=3I~ipBtJgNym|DU1+#d<9uqCxydqsoQB81j@ScjdHm;{ck9)y>gw+5p58UnvujVy%wB7urN|!;3H&ojTz)IN zLg}By(iG?L8ag#H(y*k|*Fw%JyB4vjE7QW|#RMWD;n;-)uM@rBtMmaHT-I zwR08djmK&up|&0R^s=lrK3k6P&v};yv=r_$hDYT7nlH5p{xks0Hji8k>wym0vglS* z800vMZN@w-ln`aopUgb;D5G*vHa+3fzX8IQ{*p`xn>RIr2irbVN5RGLfLmdo|@J z+Xaj8Uj94T_K^f;sHH-5N}{lovTpgn8H(sWes=O|VB>eE${LLGv!rCG^<3X(yFC;` z#$lB)i&Hc8DSRZ~!4#LI4U)ss{xFNE6&OZZ$xrp0tNLad8V_39`|({;fR}s1Wza0x zQh)K2a{Hx`&X3Ht{nU+G1DvX12cB@XpUjF zHq=Z}4g_Rd>`JfuuU5J~@v$OCRIzlt>zMu#!FNdS##93Z5`|;kS+P$(P(6_FUA;6= z;TRAP5aGZiu?-#X7hd$w@}!TC{su3ql|E@h8kPM`O*NHz!;2XMxNW~@zCi40u=8m1 z@x6|I<={9CeGbO@6x%aI%cPwyIC1&2DIT?RjyN6ee@j3cb`G2b)?^9$2k3 z&05q<%MbTioA44f@keZ<0cQVf9cqUi14q0xOVX%qwh(I(>+i? zRJ={O>Bo+OKY~Z=pccbI9X4*2Cl)Drw5du5j=2+C7V@2RZTAq#w;cZA^Xf(Sj#o$Il&UjziwG7M!N>(E+r_mBAVgH3guPG(A| z79$WqP@^qzPtez(0|;X{GI^*VD;Td9q4GLOL%D(oMZ#AXg%}X)9Bavsb?X}N#7b_h zbP7Bf)e9*&FdL2N;o_42tUsN}-he;daD_~_c3($}5D#eI7`Acb5mT<=<^2#Dv||_@ z&^v8iY-NAwED|}e>iafWrN$_Q>a=luvn>eJl1Q7m{DI(aw@D5h=ZiaRvRwI+&Rg?mmQXE@5z=|U?)-rXs7=2pu`p~lg-xKp4`btGQLZQQl( zr8^Uuapt8f{@aE=B3jDuTi6oDrrX{Y4&8jBi3V*v+w(9hoXmTNU}4;KH8&j!kK2Bx z2SUIL+AlcOAQZ&!c4p2lPT!4fKe{Q^{*dr6Y@9q?&D-QKUm*YMa;LETf~HBy7=l4e z5u}89{%?#YMc4-hANr%0(mMh}1AOJ?;^O3Fk^gS@!^Pq&87IfruNMRW^3=1TGo#5E(I}Pr0y|B5VcI)}Q6Ye_JK^ffhWPmk%D?s+%)Lz~Lq+r8Zv|GiG80|M6q2ZDe3Z(kMt zsDwZNh@{^BHfS|UFBQ|_a4?uOwnzLY^*rq=zOMAK^TeI~%-S?kSl@uH>ZYv-k#ILl zCX&uqDmh6ra#Ph?XjWlkEOnaIX{LXqy@|?T+(o_l>+LUVNsSO$I~05Vp_X^pqW#lM ztzVn(A+*P&BD&dIr9k5?(y`82m7~zG*0pV9>95<-6i@fY4*i~`@oe@Yz{75|1J-&| z6P~@v0?o9kr=zWqi80~v@`db}f1fk^>wVPKDK!477p>`COd7#If@q?)dz6OF$QMxs zhov)x%@~fAAKD5?$(2Mxe?A~4qytNq?27h!b+PUT|L~u85P`j74wetPI^m9O>_2XH zW;Qj(qU$5cLP&M*;HOE7&GsBe?RD1!8|~=J93g&pA3phfiyMM`rGip-%&aKAFH9hqaX$OrEl4lexeuNo10HJ zz0jenJ3`zjVgOq-T_o}?^2w)N?=f9e5}q3BGv~^}UB+9IZO81smDE6#K#iV98)#Dm z%7z1{qGPBR%%UGOuZ>TT7HkPxzP~CpQ^V-oI`h8psZaa%Ke-4F*G%Y`)T%;_$-zKy*d6bTGgy|zAI$g%!KvzZfCjR6MJ-sgS8w8ur-E^ zi}WVPh0`=g@7`&jujIZq`s+V9-;;KIB??KD&cDuEkk})Z^0LsXwn>Ery0KkSfH5;WS8)YpfCmdvwL*L_@mM zTKp3bLagOOfw4VHL2qc?z=T~H{z8#TA~ov>qicBi!DV?P4R5`W-E4CdKfn}$%WNU^ z+VH4wz0bup_Dj%uKk|rkUOl%oNtH$^jmP+SsVUGBq z1jT#1jHgz9Nw*y5I!lWU9Pg||k6#eqn@`=^#~+C@`tOwK-n)+_`LQ#z!`unyricw_ z-32%+N2f8lsC8_!##=fMq^!HTOSOT{0%+ zZ9PB^ev){CGj}f;?MOLwn1+N100k9?UsYGkLTLn9|wCt+mmNY z%G9)&$QJ_bUp=v({c|&N=KcBmi@1{hoavC8&u9?#Hvv9{p_H^-`$O_S2iIX;dQ13b z&at1G6{_+YQpO#nv{;3ei8ZVwCU)5daWHvp*$ymjb-I-p)je%*yggNATWq7btGUe$ zpMi-#+*h5(oW*X6z6o1xf7}3V{PESfGKU&u3N1WhYfq_7pTz3&0kZuF%Tzs_iTmat ztXFC^hz~iKz{ezYog|A!2NTQG`2{KK;Oo&*@$Qblr;Xp|M5mJhr+H?soPT}M0S5PX zkTzuHxUZjRlT1{cMpnxS_Co|4&)`lbTY(MwW)`A~KR4>nQpUu!sWCk$L9S|H>qTEHW4 zw!0(_fh6W_M-1(vWdBf7n7l*^L_IUUMv<%8V;3}>^)7F9f<{URRG_H z!0ClIKVh7&c+>FtAu@~yUw##u@9zCB&cPq2*7!O=Xr9oa{w4`Dl6rsPDV2>>7;9|m zGG%x*rCn6BEGJ&4R#lQ#@gpz%Jr-*7OIfxSo&n0PwL-_MAXzAl$Q5*F@#_@t)ym%f z(8#K3Y2*yG3c>d%cz!!9zzXnC>;cZPUdR5e8=Gis&aHql<`IMV0g24be-|1Ji>_{s z2;8t}dwF>oCKmPc z`>rt04FCK6QMH@`QB&4hu8hAfRk2OQDlkBOs0?6{#^O5$BPQ7zMg!M9S@HxGF^RrWZ);^`W+{N+8i zhCFm-?f?w`SF@S+;n}(u{>OSor>HW~(;xcsp&^x#ddK9W z@5XKk#TZ`=Q)WwgPoe>Hwy%twt0wHByH7cyK1jAllqS(at6KUBnTsI8JlG2xsimJJ ze~Gx0rV&$#&7yF9d+*^~)UkcVIM`bg6fUd953w^BJ_0De%_xa}Xfxq_bI&eIVv+*I zC!IXo6Y^@6$hB}!De1$Lm1E&P_Y873aC7z&FxH6#pQPTLeFA(^LfgCL$~Fyw*_%Lpdgw(+0r6*yT z1f7d#JnpDp1G;cktcQYiR5O3b2zE@7#n;uoYeji3Vg-#)TWqQ8p=aoy!@-S948^T| z<4eElz*-pg?Tf%R=?)&L&fhqwMy-PUL8w*Ic15DJCNKMWA{#djEtOS+Y38buTi0pJ z2qC%-RtK>J9z3FSc$Bd1pj8@A>+;UVmb9y3b)js+VvLi_2=B6P#STQ8X%Cut3(cf9 zx7q=GJNo&v8Vr`AR@W#$(hV|Wi~x%}2~yW-)4sLS(>LI*#?6jF`SbX})>0I1(0Q_d zca@4>?m;-AOTI=k)cU-+RKq^={VpT-@5*s%8q{3-=!X(}JiMD;e+MtRglPK)+LLSv{bx;QR zfGnMcbgf>v23@jDty=g1s6o0`Iy@M}7@MaZK3mA65dH|_kol?<-U{N7ohFm$#C9$y zNyq~;eRmAT=4sGVIxcPcmQC!)57;q`zv1%Yft)O@3nU7JjB3 z(4zYz{Z%Ji1r(W>Cl>BRH&XB=DNj5c0|Zm}CE26}yIA_Ge0VMhIWA8+T#OD*?yGb- z6dj!GSCQ~H&`m;KHTEOuCXPZWd;Cf(TCa+klbf%qL&I-$6o7?2O+0BOO4boi#+B|qJr%w;Y%sq|$R_PNZZ zZi-$Q3 zkO0+y9i5xZG~IwA9ZBL2B%Padt$sKdn-~;S*kTy|T+pH!?p?4%Gq4U?qaMfv*(B|t z(%Gf#aM9T%?cmbcC7VQGbIUm9V{=Q_YKQ+TKQ{ zQ)0tmBmir)ltmKeYC*jXx0a4m2hY{*tERrcwxOe|s430F%=Y{r6COuyJ9+R7RSn$O~38gH&OkK8m|>nz9tX2Ex+7`xxU<1t|dpbn_x=N*tjj(Iv?i zT+@tY+zB9da1qu#x;mCRMy4!B)E9A%q>^|G#A&lU8F8#I8uTby0x6DU3;BLQ0**8b zwSGZ3j`$La9TFt^n3lnS5wL8S>=*kFE*DH3)y{44Vsw=J_-|n$%C{7GVtKvdfndZE zpf*4px+LjM{1yBJGJO>HEioWbvCo50Vadx9Zxt6TIU>rlv0{%HQku(5yTkA-%?kaJ z@Fnm|=8(dN9%DL$EVXP{fdULQ7IoaLM56SBoj8KH;)pZ)@-V)V8D$+PD|kpA`y)nB zP{xtR^C1+(6ez+Sfz_Po6L-YrDK{hl7jcH)XsXBP)1rCMiTBWjU9?XO)9&J%lAxlW zZC!q+f0^3jLHyH!)5r zpJK0s$h@*M&M{t-5B2lhONQ*f+;UCp#_g$!+Dpb42W*geWoA@kbjsc!PLHYqd(?TI zdp>c8uz3ezS@{&*G+xOWljwp9H`vo8d4?*(v~;&H)4Sp^DjWIYF|pUid7)r8tW%2P zf_Q$qTe4|raei=8(O)Pit&J&vm1+7GYMiFR6Jq&@J^ zEpHWUN8J{DXr9L;&aGm~4PpSe(QS)5{)JUhwk01DlsRw~R#CLYA0m#lXXvy>9)d>N zgAPsdBEVc2wgvHcpt8(EsJ!biF7(QnmSd3v2|Z_#1I)^Zmi?a-wg)D0DGC#ZCA969|ba*i3oG|-u7KQOYA4T)(6V)J-djpBgbZH~m;k{Erf zf61>ym%LfI1(+S z`{|k_F;tBEc`-S7b}FDy!g;JkU=z7xEkyd43Foq9?;>~xdY&Xd$o=-QZgY=4Z-O?& zA+0L#RFte3Q%c}fP*vRe>CEXq{Mgp5n9FxAHAUwV{X3|W0Xffwf?I_^#j5`+RwAb3 z7!QN5^)ICGwO-iI@*^~&H7?KNNxU@e1F-lJg%0sT8(k^ss(uSsL?zytIf(JhDz zXrIl#d(AEWE!{1ai+B77I8Q^$SDXv#3)mXcx5Xff zJs;BBkk4Ds=r52LLKh@6-LTzA9nddu9;mG>eJ%X5$`~_<(&}uTEKIh8reGch@uE?pR=K!1iX7A|Zkkkbxi*R6gEjwck|G!$RWgq8ZJ9BY^26_?#50x6(G zBiYFfoV&f0cwy-e-25U_>RP=Lteg{-XM$SFXY-kdQXB%j6pVX@sgP5ds{^$q{k5~J zmc%O-eIG&9))ePI#ANe9Z2T>ws<|I(UG`^3_y;L9r2(~>G+f_pmN+cEQnN`Xs<5+r zhdGV=9*uF!ei_X7K1$55RMQ4w0R!hL7Dv}ywkG)0rhWKH>KLx0$&vBLwcA{|fuaiT z2;<5He5}@%|7JwgFR=GtrXG`2T?O|&hI5xr*X+*g7)1H`>|^fx8Fum+3{d{u6Y3c^ zd)kCQ9M+Y}h!P5z_y|@c6lp9mkwjq9H_11A5tVbal$eTNY~Hc|)2bht0AvwqaUqe` zCo>~iY)Y$NYs4Xcs(vtNL$6{A1G7*>7Fk}RLYQv(BDPql%XOaeu{i$CE|ho42KLG0wEzn&ieT?3^oLG z0Hg?zLpp^w1pfr#DPm6saRcQA)hdEU20sK>2O&H~d;w|D18oL{F9Psw!Oi%qk-W(Ru@J18M_i1Hu5_0NMc70MY=?0O}5k1&Re?5_%G{8!ihr3-W_84eAb} z8|uGEL;_C&O#({-NdiX#_S!{RsmI{l|N5dt7@M8$WOe^B;JGq#m4}zdhf33VWz~26`lVXpATw$fr>C zATrQwAQqqxK7bLnDLsiWWGSPGFlf-%)DS5|NiYN{$Vo8t|5fO~gz(_w0naF z`;N&U#q{0wL1&Vyc68bFM4v0PGO#V#*4VwKT`N_v*Kd5|Y4FWrzxZ?r{|R=i?92>q zA*!|tTK_o)Sc7yq-i^7|i&o>#yiYA2oxUBA>0*i2+xW{fV<~N9URkB!iL)Vm-KP(K zF(c7t9V^X1m~*NVRUO4m()vEMkg#vWR&G4IjLelVU&j~O9l%-pnEGp0n_agD*Qzvl zC_QwtReD^K4(780DMKT;5khW>ZDAyNw;a~Xl7spRz_mWoXo50iSjM-(;ZLYEx6aFE z;Fz@9tC*Q#2xvTEtQcE9AySZ`ndEb0=0_`U3do#fei)vEl~U(#kG1XRGwf%6Q|UYk znxlSbOVkf}b%1S;*B_|r?P|%g6&m(#-0zNFAF}(Mh2g3B+c}{~{H*W9@(!XsW_^-m zZoiHMsF!4?IQU-mLBW(7IRAOOZP!cwx_Rf&rgC6uU}+_vQXk=+cW_>dBvVSoiC7lI z(14nk#7R5ePyHGC$doc~E@|Z<#xo{6Df?>Vami=Pvwq>Vm#p?K1*uLoAG!(|MAN! z)icga9(G}t`6QW`;NS<#Sxw54s`Tl+P`1SJ_d9y;sLlafeUefOAGx8&GCGzvo7@$u7;>WCU6_;9>u^eSc4j z{rCLf@%+>q$lm?eIg$4Q`E0PcSY6GZnrgnf99ahYmN^bvW~^F&%!qp%=r}$gI?z&z zA60-2KXV6nw-0{@Hzl8A-)(hv!^=tahe6UbuXnRE1~f(aW6B@$HIxAs+WBQ2*u@#= zc9`1QKK6h66`uA*un#A0|F}HVYA!4kWkd(KY=C?kmn&QD+b1MOde zv04&jsQQ=*k@;Fb&MiTRiw0mnwW#2CTk9!wl zRv6ajzNK`Ng}~^QZKggP-OaAy$H#pkIy%ct{cIcei_5L*rqz6#*@yO1jVR$|JB$jR zz+c+06&lWn;pxO~mjOS`*=2vJD))B~3VYO64F;A<*HnlmFwqS+y(Iei0?1iw!&%B= z(xfH>H9>n62mU5m?_NgPcgg4HL|Z&%84|^NXrH%;rmD~78Fx2rDgSCwYBkuj!YB&I zXa*nmzE0#%1en~iC7B8Nn+^xL;6oLOD_PZ5r_1oNi8QvbVe0=1!~HuXZ6|wEROHc) z@7;ad;dc|a62w3qqFJ1AhTX>Zq_mDk8Ouy06nxkfcG<{(thoVMw~)c2kPq^cRM zb*i4HN{@+ub%K~2*V*)zX1LjlNPe#h2Y4fI3=~9pEOXynOYayWN`0I;k^=6;{qr?&Wn(~ zluw#NiddZ=WO7N1l!XcIu)A%mSL2?Z>+oq3Bg1WY9DCH-bCDS#ku*{XT{6tYT4TPi zST!yP5)#qAubC2ngvqD7gox23e$RE}koSW&>eid6KXw~?YW6=>c%5=5vLn_>ib+~E zzS4N8stO|f$w)L;vM0r@ERMc!E_(7Rnp7B<<83{}Lh01@PY$Rz_I@3+iMEnaW0 zp2y3n++m4LPr~^8`doUHGuO zPp#K=zR_0oz@@Y1W^FG63xQBBV8u;IBN`Ra>@!==D1189pPz8q!9rPVvH=d59eL(w z?CR=WQyi8ps1%QVIs%v2Xn%3t zLbu9|Pyg;@_^OJLAgHx&<5EN${)zu;<>;1BY5Y|9U}hO>5jH9;3;Sfagr%#iZ=ExN zlFXs{3fjSi&e~gZ*`)Di<>G{~9OPuJ)NYL+pTt(R+Y+%)h9E)7Y39qb5fqZ!w=opH z%kAKV!tH)@_+2PdrxWILiIEmwNY1FG+Q zyE{AbVZMJ*gowDb<^OX?XN6=Q8`%iU^_)5qw|O(J!GZSLT}e76x^iU2H|zt?A}hz?vVKprS(dmN(%fMY;KtnmolLvrtaG@Aziv<7Cv0y2m;r0i!(%O(nhLCeK4?nb4;<#|1L zU(hdGv^}%B^W5tNG{_}8I=u<{=(7nLihkYSXsxZEjo3Ic2{z>!p36*0TK+TMnDt?N z@2-sw6xS)y}s=w8t}f^U3O9BNB=W$E$RmdZ{a$r zskwKDGCwCPMk>hE{+9G|N>JcSAQ$>Yx3+dm{9fsYdloCG-Sl}7`pM?rLkgDfgP`^1 zUewo3SuQ`{^88e=Djn8J(PgDQ)2G|3|H~Qo5rQNwck9cMUH2$9X-e9^%NzOLh=$_9 zgmi*IT?LKW@(LQ)X3pL+ZmmpUAyA^rf7Qeh-lwZWErOa;ssHg+|M~H?ZCM8m>8LZK zfPGwhGjG1N&NCG*5P~0xd>>PLPewNp*aG zPVeSX%(coXv+MRj+w~yQC9=PwYsoNO-CbEOLfg0Y9ig7!H0F{@DPB(dhXWNYRlyR< z@V>Yq+XlJg%TNfGkFWFGt&`599EkYHJ#TW`Xe=N*%-Utv70Y3>x!!Ee)2qgZD;1|c z&W3_NY25t!V)h!*4VM%s?i9sUw6e-t(Q9$Kt(k9S8uenie#7%Ng#P^9u~P879T+xu zzpfuPzy3EGLvDmj9^@}V_ekAK9hQ#nXGNF3u29#uynbef`4cRSfk8(hAubW&V^C&b z#gyViw`d}s28x)=D@=4^Doh5+btZ!v)VBGZ&E4wH33GZD{S1MB&HQ`3&ijJw&iiA( z*xB2M>!vtol9Ye2FAd#Txw^{AXnXx~ms$E=&dgBW)cRYlqiwC#UB~$coHv0NJswM? zzK&N)^;(J`Ao})`!@ImtJwrf&UqQHNNo}out~tk5$MLdZ0k*49uAQxNxJE# z{CI~gqj&G}_4o`>9w=g6ps$3|MnJos>Nkr7cD1>?Ed$RAm^=j4T^8o^a5|?ATkf?g z_A-=SwN6kR*njZN9x2@_%4lm3!y%GJk#hU3NvE~*)M6WK5((R_c}y!_&f4gZ`BBq9 zAIVXFFD#@CcKrT*H;8m96z}6707lY=h;vyK1a*)8%kl$ox$B1zdBJ0*V`+U4@oAHR zn16egZ%9xB1fr4EJIq66E4FORPDx6{`L;hpU8nI4{=J|%IV8$gzyd)JZHwH+Q=x@reX%~{>+i96|<~k-qcH{`(9`P zlz8c;B*!IjsoHZhJml?>7Spn_*8tn;~;{=gr%ws3Z9|avoN5dxg8a#rl6en_B0@-%qQ2lmC0KCllV_M<_T(& zHuh^;p+L4Y)w)yGVuWtql}v$pbJ78dS>)NrJ4adr0*0W189+01(T#+S$rLQWg08>M zlZ6*H;Uzp-4xVodKbZf@MqpB7x9w>w-x@7nYj^Mn6K{+^dL2eJ@T8lyh@_zMNaYl9 zOPR$T8(Fa}U_Vz{M|0H?wua0`Pf>y;+RCBefAA|)J8SvZ-;d_w4Es*Tu2xc=%zq^R za5MM(uL1tI{b=%s=@s@p%@6Rv;<7RbFOh+3j4wsCWS0r(FAWK-iR#0`1*IBL5YB+RI(G{O}Na^KVhFpADu zpj&&b6w4l;G8Tg0%LDO`UJFu?+5slOM&bmkVn;#u`;B-?48n~1a1ru#iYsH!j+q~; zMe$3aQoCrkvWo!IgMu~r+?MQ9Lq0JT2*HO?Ah!^;;ipez1+g$`X;7z2pDJxMx5@g4 z{#1XwU93~?Jk^);{yOaf5|_M%OCv$j6<5Rs_xzxA7t!pw5oYl)YwWnB8i63d`5024 zqMn-v^+^C($0Nu5Q-yMH{^gdmz_cUJRxy$lE6TD5(Nbvt!3s3fj0Q28)ao&G6`qrE z2K*DTpKa`Yo}y?2EHTS#bPuW>-GbHU!TzV4ZE!|ODVjIJw!r*uMZ>o+=B)&d+ehs#SvZz)>{1jG=5?V1) zPj*`oj;DVn_P^LvBIzD}<9E4MC$K&T-#@m{&R*7gBII$4`^-f-D+qD}=)@?qwSl8S z{<>qjXnkLnkZ;9*32XMhh< zzA+T~Yu??k-W`c46?Co;ok>z5c(dxD|XBeQl53o_csR6 zD1yM{HXHzR9R4AW-y9==9QLPt*o=`1ZzXx*gkVQ-VC~?KSQnaa33MlTLV+}K#@^~X zS9HV3%1s`sTAJ5ZIXjLEJ7rLga(3PwOV}3dE zp_pXPi@&-*_|{5nO&8%;*QvXNLml@s>U=@GKYR66N*5D9ljcwwn;I7fOIILEDv>a+ zdHa5rBGM$HyA})u#>%w>E}YHsO&;y^SQv#`9Z0V)mVU3~#v4SwY2K;e4*2?*!|BFU zpev1)=3(t-hOYjSbfx?w$4&ZeF9@TyZmm4R;e(FLJ#Oex7XKiTAy*j#Z|!rj_oeuD z?{abdu|JztE@~`TfN*s6C7!}9dcWMARR=i>j$%b`^2{X)Xb(s%x9G#Q{5BHd#r`V! zol6O$+PD~tWm5vK^Vy1Dub-j1V|4nLb$C^V@|bqeIQKOa_j!bb4Qcj01(9>?xlo)l zEI*#>g=h4`*Xwc!;qw}j7mqWyEgs6O9kRgo4z{dU=zR(+a`@=XmGM5)&WLJtT4C#F z<;5kz*}&pU0R4$(@p8l&>CyaA2(4a_?~i0vDxuhkSIhq0&{ic4h415`MgjPP6Q9A_ z`%+^|C6YgHaSPwZVIKKRJdT%fjYV+BW^Aq${|>x|K!0UES2(gKK0dQ}S#U2uwbd;CEZ!5|DHYwCm7k8*MS= za3G%%fVilh{&7|X5kKN}pB&c}@sc=5YtK2V?%p$wCQvr%({sf=Kv z47$WAa8ZEMV)dmmBwmGVdMrEU_ph|TXJz7{@jrsmjmGdc5Pl?oT68GLm0DLtyC7Hc zT&;)nPV(V&tR-dmn*@<$ZAGkGh$>ZJsp|uZAMroKY6B?B5$oi~k6A+;wgFCbd}6H{ zw@aqt_1ZnlxvzY04NxmpgLfrw4evT*+~T(tz~3~DoG6RYhH?6-p%5abOq2$My|mhQ zL?ZUtCdff$q{(G1D`n^v=dYv;3Hf)Hf0Yi2R91JOX4^&@o3&yVr0wlM}J%XM|9IqkXY7(!7U|NfZLg3NqVWcAY~d! zQz6XPT-zqzq0=@(U|cDlHM!3&ILAD9jAMaSrs>>pz|e?neGOaMP~eimF}jQV^zH4g zM(r;e+>5Bx((XNu9F9S?*}aQP$hY`)V!#RBd#%dEG_#%Q@GOY{+RjkUu!m`x$oK86 zX7ASBBO`v6^bl!=0MoYBtV2y?xSwM9>;jIjkS}!d$bAE)ko`4NsI+PoC-1ev#Y-%n zyD8HRP%gV^@Dx-G)!Y&M8A-~QB=&ZeGs~pn>P;-#Ja_8c8VG8cWg0KDkFy~u23GN$ zl;Xtfn)lAEoZI#6Que+V#*Y#^!3je037qu(MdcURP_C^V*}iRn6>Pu?o%@*DVl`E{q(fft6Zx_n!K_e z?chE|9RJhqa|kW6FV8m#P{}A{2;j;G6*>fRbihVK+w8xV{A>B*R{ zq;0Bg@!xq8UvFD{F~gQa2z87SqN-`2xiT!=QDE20DJZ=dn$Vm$cs=5`^0IStyVg!0 z5l(y?QJ2v0GK%xaP0`(TKvE#;XSpe?JQ`R2wt_Q=Q#hRy|M=J+U%{cTtUwM4A5|y} z`_#Zw-p1~U3ykPj_nM`%v%@>SpDKfCL`Pn1u3&^pBMLtFzXOGT*=9onQB&GSF*?$t zp$|BY(};~OA(-5rj30zz_|M@izN(3yFO;-?o>&So0PC} zt>Im`!w?5dbk#<4IdIS;#seF6#gubr_W`}4RyFm??qplH{s&V(24(~RZmkNXV>nVo zRr|t$IdsL;m6~>GCr>fR3nQ-FfE@TNKGA-ZImp>VR5#Dx#uinTXi_+rQmi-+QNo{x z8)iwuL!yaadgf1&@l@PT0@@@R6bqnJvo{oD>e(gh4G!maoxR$79|8Er`{y22M8W*! zHZVpgZdDPJuH@D~*7ID4sa-Qv{3D20)|mzD29aENuK-R_Q<>N*qLl8%gIj(*r+>Vu zr9JgVJgmMPv&5((pB-9{SWD%LR|#Wvv7xXYn6Zknc6wcBjx4W(EdAM<{6|jx+H^`r z*5)KY>69>SPrlR27{IR}u`?t)L&xd^JEfk}E1vMz-ssvyLZo=Z9ntR`@+@tzRgf!V zfAhEg<}DgC8|P!%tFmwY4gIPz+oN+OX7=kP$=>rQqTu*5YBbW(37O2Q>&c z+7e!HMLT){|Nq)vLjpudIL7EZT6blF!2ml6pB=kpe_y+Y@jFABBJnxjn1tYy(wna;d{&a`I$MM;DNjn--jzJnKF%rj6? zZ`#V0YqDr5Q~|;^6oEzcKhi0p?o;q1Ewzv-q$XdEol;iuqj{EcNCU6i1zIj>*zrPH z7j~nU9ev+e_1PFxy&u@jvwo8X^Bwt3?I&02NsWmFHashT&KQPP#a{QUGKXl}IJPR- z|Fe?Ji*rX%+NEt($KAA`xu_K8OR%f9 zFJX?i+UHufPD?M8Y*!O5AJ#C0{(g(1-n2Y_i^5(YTe3LyiO^fHLfoREP$iG}s_57{ z&C;~q>O|eOM?-C4^;mZwN2c+X38i6N$D%>Zs;s7YPIJ6TeW|c$`L5{CKEYuZL7Hue zeM#dt7EYkvia^I`)YhM^v_f#ZuT`xAo8 zUn9XP>n+!Cobj}uMp63PU{f9iWNja`U&@;+Ny!C3-4a-7G0e@y+enH8UDc;s!?~7L zmDY&rjyE_}IMjZ9YZZBM4)|AN`%wdH2T)!wVF1@f_2V)`dgsFd^yMV{PBvP8D;!!u=U07DJ~>eZxZh@%tiuc1GmYYPGr$HSFIQgK{4$`Xs#hMS6R# zKmld3cN5X5tA;8#bMU9-{x22e%Vodz%wxXC*y}Qix4%Tx78=!Dk&Zd*b@4Do+{tbwrJW1&wTndE}*vkFCemX2F=$M{Z6;a|Vl6ioE zG{;TfzvZJzMZ*|N6sk^*DcX|x8G^Vd3g22=h4N}e^tq0h~d(JBZJe+Y#66Dk9UJB!@l;`ju8m>i*oNB zrB6u2k7L~FXLDHPX#O>~qvV61qmn=^q1)rnEn@A2KK?|@mlN$!gmny#$2$f$Ql*qw zGn_b-r+-g}KSd%@fsA|TVHXh1GZW}jdfzloHWvl|~q6|*K=)OVZ~ z1#n-gUtuqcbxEPdx(^{ZNkXtl4Xc5xAJJnNF0jRw!mWqRuNWW6AL$-(9s_f5F;yny z`dTFLvrnll5B6d5w-l>dg@ zuB5K;$ioWIYwK#YDQ448lWxYO3fX(QBzug_DEfm~dZRorTC*!?SBK>G_zOsP234*| z9L3(nJI(Mt6JH1)X_jRSsD&wnDZ6QY48!*J{FN}Fz-7yj z|LJQ%zA=}QP#tFhUCY11t_HASB-#tV7w;P zC)kE;G9hIci1*z?=ap296HZVHHmfOC7KYzn3+J5QGY3HxFTW48Lb0JvluZUOmpv5~ z@v+Tr@E}dhFx{iuw6T5dUt{(?O#vw1TXB$Q0Ovy|S%K?@;uU_Y?J# zn@ETdLtKyvnrDT*TYGdMFc2dlBMeq!Y!-8or`C3GCPw?}L-PogF$KM6uw+k45tD#7 zjC!SCm)#)|oiMvc=_Dh)OJLC(SU3C`Bq;=6yv)BX-kB&Mtq~aVuJ{&sLcU2WO#ZIm zCnbanHo{HIECk4l&xm$tv9adBaQ!a*di`;Vq1+kDL5E^`fh|~N{o^j zL0VxJ&U|8L{TluJ7^~>~7`|ZR{sHi4#zd9Kj%>dISQn$2@=Q#?-vj1Su)iKmsyb(l zF^aK@(FY#ISZwXcLVY#ww*|9Mo{6r-czn7f?l%R~0_aMuK5xvg`2Q`SG$=?dkes6| zBGW;4UKJFQnsMkC>o@6V>mNQ94Q03F+mY|b?S}Nea4Q%#S9!Q45wqW^zZ9GVb_FYdoiXqz+$iAC@gS3n7{BR-wZJ(F?f^9XKR$M^ zE2ss@k!1&BhrH*KP6|DSGD}<_>H%_xw_oW?Q5gmb_~^qVCFCe50=<}G1^rz7hJsmC zFS-TMk!c66pBAGTLQ#4>bK6^2@aMW%zjRAI!1G7FYT;>=vt@;#3lL;KX?#bi7ZP@AkYK% z(zHJUd)!L=btnFc%^7hErXIFtEdz;XT7bwQz7_p~%lWHOa4T}ni~xSkhyZcTiXM`d zX%pl^+G&IwO>*i1R5Uva1S4lV#9;b46eBx41Z}D}05Li)2SJ;b0GwVKy|-xqWL7?B=c#&+sq#TR+!HLR+=vWR;3fb>U1q&O}YWFHa%@|$!#U+R={!T z`GBSABLT;!j{$!yOD_SOkX{a0o<0?DVtOUur1Uz#+tM2VE7Ds4E7Ru#R;4cltWIwS ztV#C*)}{v+msFIbF9IBwz7()DeFZ&-!wE0_252^%Lhgi9;Q~14EyQ;%o%r5iJHAut zfwSD*a6aq8cOC<9A`Zf7h2HtnV(LX|MC2o~{|Gtj74?6;oVH9?6^t?m&g%bXIRVaf z*MmAZ+t$G;a3-ADY;Z@QZLyNe=Z4B_;OwcP-+=%(jjMA4+!2&z7Py<-3U`UIaN->Y zr`Pdtew+X&^oellz75W@Q{W8xIk@Y59_}R-Hz0rQ+NqIac@^0R=hi2#BPYPgcMxwH zg2o%dJFb6%D!4Ty!HwqcpA$&SRk10GnQ%|*g?m>Y+->fGTg1I^=D!baRrkY9=__#m zcmRC+LAZrH1owc)&`zI~8UoxSDdt}R({2bW5vvfZ5o<6Ciu`+3L>VU_j*dZsXh$jf zj&_8TqyC04^@cES2sT_5Q*HqNf7l(gWHxCfbI5;OxZBVFJMaRzC5qIah9Ng>2p1_M zvNF?kp^9Wc+_v6uE)#PCdGfL-lHp{;4N!q>z6y$DB)RzpsK8g<qKozQDRT5~OV1Z!^iJMbd;I@v<#-a7+7&Fv;n-GE04B!0u zKP`W_GA7>;IuTunZp3!P4#ZAG58_>jcO!ZcyAXYde#8Lcml1=AA;d6ZH)0QBFXAG^ zKE%a{_aH7oyccmP;(dtA5bsA^j`$VC6^IWYu0(tgaTVf2h^rAFMqGpVRm8Q3k07o? zd=zngOrF{QF~p6Ck0WkEWP3A<4$QOIntp#8@fpOgBW^)_RwxwhVw)Hgmy7Ggt>O-G zpLke2DV|k{sx;MbRjH~{WmmPSf~w`J^{TC^9jbk*!>W_2vucBSvbs~fNWDtEN&UQf zxB7tksQR?}V@-m_swvb=($s0@YF27r((ctB(!Q(xKzmVV(&g)lb<=bWx&=C)ZfSo) zIAKM?hQzkSC5dbFM4zIU^dECeL%lKzfXT$ePcFe zv?b}~r2eF1N$)3JFz5~0hJfLi;hfQA%r{Ol))~FVb;d2mL&mcvgQ?B*oN1?Nzv*4m z2gzy4Gm~A(;p9!p&nNFrv8GH-X-$6#q`Z}KBIU!>+SJz6_SBx#m8lz3Ury~$eJd?D zttD-F+McvG(vGFQpLW5lH)or-n_o$9NMDe?D1BA>*$hKQZbnhY)QoV(_KbmyBN?YM z&Ret=i>1I)ZmG4jTG}l=mX(%`mTi_@mI2EV%PGtGOl_tmvmmoPvo^Cevps*aCv#=y z#>{P*yD|qdk7S<8Ja5%nE!F~SxwY2XYHhdnSXWv%TDMtuSqH2~tf#E!v$R>3tb(la ztlF&BtoE#)td&_Cv$kdJ${NTzl65NUe6}{*l3kEpo?V;Wn%$n=lf5!~WA?V}UD*TK zN3u_4pU=_eSaJ$-%5!RST62Heb9!=C=4{N_ma{8oAm>QVshsn<+FVO+L2h|&ZEkCB zdu~te%G`~)+j4j14&)xmJ(YVtPn&1SE66L)tIcc8YtQS+TbZ{pZ(H83yn(zUd8hKu z=WFvV`33pqaEG9tl|b->mUBkIpO^Ew2?|~t!>fT8V|Xngd1XW=#PEM3j>!3u+vW9d zULtRQ%n3Pv%Tjs!L-=(H`5k|QKPl&nCMo!p*TIASrMu+M$G;@!rxYmo!WbUTEmOuQ zp1Y72;Z&Q(MmY5Zqn``l6E%M7lMg#DmQIrx{rp{wPT$FBrS@{tRWmtV#_29j&&jo@ z9wQ%R^%^-}SEt}t%jQATI2V6>r>)6|PZfA71p3_cF&oJ7$h|xJ}PIogp*T?9*F`RP!=RYT(g)b3T*N@u;_m$FqM$?=#xRtS6jk9-ozg}YP{DI-%!HL;Nv zxGTHhl#6xl<16XD4;fu{gwgxgGP=B$Q@(P)!sG7>J~t2Wxq5)l-O7#7XX2noK3J>Z zZ3@0Y!3TfjW03K%`>a|emtV#DQ{itSpW)H!8NL#}&e!J_F1KZia<;edxb&<+`Q+JYoIWYH$<~*Y*4@g-{oDq*$?U<_e_%8dQYc)1se8w|*YS``?qt)z=#2 ztNFEloU6pBj+3HiN38$a$Bgddd-?0@7~S8*==Zs82lz>DU_YZjSjFgp=|rbi=y-pC z-xGeghS4`BDeeBoF-Cu6Qa%RF6 zr@ZGw7Ws@Hny%p6(XLnU@k4x<{V`u(KjyLYEq?O(32)^m&oO#W%<@!?pBJZc|XfPSIFSsOe>uxC8N9^-reFSzF) z=co1K-1q*QpZDIKge!N*O8Dg@PWcJv#7Itgq&{i6T+I44kFmeut^AhH-03B#@sM6l z^BwSae7}F6?=0{06V30Z#n=o^8o%Es=l@hG=g+-JbeQM-C$TqBXz$bY@>PF&aWY!g zbeVnXE)pb*$#TMXqKo`&b&;PGFY;T@CBAMhg*jy>RDn$5l-&aHm)nspLYP z1><(5P9|;*Q;FQZrgEaw#f-+(qIm8_Ug^1liEC`y%qhE-3&|EvTQ6TPc@?MoIAv!8 zA!RD3OJq?M?2xjP(bWC2-9ku{zlSEI4VRr~g|sm-@0n5ll!8B}kUxK`;6L~q{22xR zehd%#W}K4Ug9XcE1z)bmh&TL%G)&Eh@K!m0>vTC^JW|e&O_2N3*fR?Lf}Af&Q}7lA zZ(|GUCvKBD(9zc#?xVxpSDoWSB!s@^Hrzi^IN-J!S9vx zbzwPQU!dTZDfm-z{&s~w+4>dyc{x8TAmx&0dt$a(u3IX}Be zUVm=7f>+pUUV?&;{Y(Jj#k>JIzh`aCsS#@Aw95QN%vmGze=%p3f?p|H56H*(vzXH_ z^A9oST{)k>RnC78YnSsQ$H@7D4`lj_qj$*cC9bl{`G*SS{Cau(7N43f=bw}B58^lH z%K2R`IsdBsT`jSHnVkQjd_Kj)o8uNcoq@5G#ZpyZuw^lyKK)Wj(~M%snV*lL@wL6f3M zg(qo5Yp6F380t*>P5mZ3-3WgWJ`~Ohe>PQ^s*oQ~+Y!@5`d3X_Y*kPh0WHu6JrB~q zMvlA-4E>5aF-c4jGYqwc8Q7)@p4$nX$HDiCm%s^F9sLwV9ev+eMV=!s68gVIy+n4B zJwSJpy<~qs(0$|pIb^tlh=w|Y9kAZe3^>ztnyADS(EfKw2Tbn+%>e%QNC!+uhzQ(K zzyZ@SzyqceL451y{`@!m`6>SVx9qv$cGSU!I?SRv7#gso z5lfm-t2eOMgV^gK?DZ`yIgBOm&=UH;QPI<)<_v$XCqlNueEbD$u^iZBA(`AKWD9v@ znNTPck`=;y;ZE{^;1#;aD#0)K$!g)tLYO=(tQJ<2M}$qn6J(w6N8yiTy>MPQPrfGn zRro8}Kz|{RJSJ*IE!ijxH@_liGxPc6akBg6!ABfM1KO+ZJ zMwN+tqAF9Bk&CKIRW-S!s#nzuqUveY(}GGJRzEAKHBOCFDAl+%ZehHpL(?IYX*?Q_ zFhLX2goJWUx29W|sOi=83X?Q%YgY-k>6?G`4&i_F4<-r1MMH|AM(i_u!SIauEu+hL zm-r{+ea1E71(Rq>P$ig#nTDy7O(RSrR4JyLO*gAjO`}YsRB5KsrqL?1=@!#1s&vz> zrd$6vd*1@)Q`P;y_g?#)eZJ?M?>>9P7(sL^>(C?#2}u%@gd_B)7!mmRmw%-0$~m$o(?@>+Cr$UH`qkz3=n(d*0{!JnJ*x<(%_fpSAZ{YwdmZ zJ|KrIE{j8?EGbJuPFY5lfhZX-;~|$UE6YN(EHBGLZdp-Qggi1qCcvGtimU>8Wui=k zyJS^a74pgIvO3%?lVlR)m(68!xJQ4slr5ovY$aR4z49gb5)_m#%a@^$Y%kkGjO-*k zL1Echc7|B_s(clS$eyw%6qUVYZzv|;kZ(Yo>@WL6aXCN^fD&?$90VohJMtYUC5OtP zP+AU?!=Q{DAxFS{a-c&H#J$O(T?QKrgN zs3a%L$&etY$SF`+PLtE1icFJf@PPbGeg=v1bNM+uC}+u8P*u*6bKoKQh5Q1l$uH%X z@UTpm=}=uRl8fLGxkN638uDxTHPn>L<#MPcSIU*}sQgBL1GVM1@>_UJu9a({j{Hu3 z2X*E5@_VQ!H_DChxZET+L4AL@MQ(v7^|o|32FDS1YofkyJI zJPS|D^YQ{T_VRoAA;~M|6@zEI;$CrR>Xr0L!n0m!?>=beRrD%B3op@2gy+4gUR7x2 zRr9LB3tn}vI<)p`cs1ZfueMhk+IV%mI`EQL&#MP*z4~5#c-d>wSm{X zwq9H4=C$+ML3gi%*8zHX9legw(@XY}p_kXi>jJ&Ku3lH@<8|}8!RuZRuLtz?dU?Iz z4X=;a2l{z^y}t0K*Ux|J2mL+#z+2t`ZvYJNhI_-|ZSOtrJs9Y{@4XL$yfNMw80@8Z zDe#Ur&Kn0qyz$<6_=h*an*c+-R4*0Y^(K3hVVF0~n+C(ZG%pQCc+AWB4CEPL)`(Ns~jo^%v3p5PMD=~sa!By z~Q+!&hp9+5ihx zhRT3NYO~r5i`9QtwH21A?P@zLRXf#A_*(5&yJ4BytMCgazM4*bz3Yk8mSg_&!2LNZ5dc z6l{#h7Lg4yBCN$FuUS~#Deq_-sKZ}9tMl++i(b8yTbTB#^$ughJ zFAKUDUZt^5TOeN`p3`E%+Ssnw9W7 zEFbw>vW(U&{TXFOUof}*AK~Y(OgE5QeXP1xP``gfprKbn{z}U{G(U}{rD%DYNNdn~ zSaUR^t!W3^mG;3pV<;U($I~fv2AxM2(^Ygm-Aeb;!}KIQi)SvRE9g49neIl-DS8nv zYoULlSUwhmRYh4=g;i&DSVPv7wPNj97uJjQV*}Yxl7}U+maHvHW<5|dn2lg5ES06P z*(`sZEn{m~2HVLFvXksQ%LEf7L_%ID0I^U4&%6p8T*wZ2P*W5ukBU$gYC(Ny49%ep zbcAlu7Y4#G7y}bv8q9?Guozar8j=S_!FZSgGhiNSR>6AM3VY!woPo=nahqr3(L6to z<)wIep2%zPdb|;D%3Ja_p)Lf_R~Z&n0^qR)bq3(zs@vj~lJBE5{>=f#y zF*(#*W9QK8h@J4bz8X7*-q6@7)K6n_=uM5CLvJA_<8cEtb_~6(u~TTE#^lf-jh#d9 zAa=&%hG^^<`iI6&p`jX+L+@(r9O_0G{%aqUokIOlCWi*2>>L`d?SCaSBH;I4z;AzK z!0-Kl->87!=z!OlfY%2BudxBIaRILn1770;ULOU#CI-Ax174E?UXue}9|ydq2E3*P zygmtdr3Jh`4R{Sh7O#X-G_MJo*A&g`vw+u(fY;{%ubBa_Sply(0k641yL}Pxn-}o= zGT=8q;I|;)mmcu?D&Vy!;I%m5wIqMwwKU-Mb--(Rz-vXoYh}P|Rlw_;fY)@*YqoB+ zg__qg&FkBM*P4LW+JM)(fY)~cukQn18v z1iXF-c%2G(oep@N33&Y&@H!XpIv?=55b(Mf@VXT6x)SiZ8t}Rn@X8F@?RpkJn`H5` zX%;`5W%08i;CEQ_I;nY`)x0kIt%fnSAt_APv#}VT9)p(fJhX-v;T7lvo#9pJ4p{fW z0C*dt)gT-%?S*}?9}d7lI0S!(;Rr^iV{jZ!z)AQ4PQhu6Q$NC4I2ZPx*c7JgSPImH z+8Fa%Kr46wI$-2WhAtTWdO%O;1-+pUybhx=)_sW)Z~>&lSFjKkVdPr^OW|u+2Fo!j zuEaR_4XlQ5!}sZNekngM;IEz|M2}RX$c>#~giO?P0B!sucwSy8IKqF=m@&Z-srYYz zF}MvOJUhP=kBi|k#JTMZ|2JZ8`wf4WiieT+4sLLh3vTfcMq-D%Jj^BcxZ?hN1@}4O z&-v#tUWq3Vmp{NCAQJzrEXf6_Fc~BLr@zMQ*F2c(OFU1&M3{)zoCK55nyE0AFh~Q8 zFzB%*_=|ht7?HW=<(hwoK42uCMB(w1@VK;J_2{p(9iC;PWvTcZlVP&|bP%TDZ+r?E zz0lHc@i%-v`uX|w&Dtk>wNGyOXdWJgJ~G;|S-;rzm$iT9#vYKN(wy}RW@G9Ih83D|tRO4ND)J3kO}-^-$Xc?Fd`H%k@5u(T zkz|lfWHZ@9wvugRJJ~^Yl3ips*+ce{ePlm5Kn{{a@d9hjUSw_9OITyPjFm@wHjZs(Ti8~%jcsQ;u)5gAcC$Tf zFWblVvjbRb9Abyr5q6XvW5>Z}C)i1F*bnR!JI&6pAK8Cdb`EQi3+y7h#4fWd>?*s) zGTC(u02CMiRwM@2DFQ4AL0zZ^kL!A*2{eUg;U#E~70DaW58i}#;eD)2ro(6OIaVff z;R{#;YhfLHht_KE%CfH)`)iNoTEI4X{b z82 zoKKzU&S%aH=W}PKGt2qPS?DZs7CTFvrOwyRGG~?Zjq|Ou##!sEbG~!dJKsASoQ+O~ zv)S3>>~jt{hnyqMG3N*8wDY5L);Z^#cP=;=olDMT=ZbUH$#kx}#HB8C!R4;un(jV# zzk9$v=pJ$pyGPuk?lJecd%`{G{@{O}a!ezprm*eFr(X*z^unn7*FqENa zNj)!G%G_ffq=!WbQHGw>bEJPi+HcyU8M7zaU$LC_O8X)!rDsZ;={eF=e-T&5D@z&>3oDr<(j3of z7tG`Pd-Z^HAw4iJ0eP4J9L;Hwcp}ooQMwN4d#afpUwp66Jq3XSLRELb=G< zqUAP}-#9x^e(UT)xz;)1A0u=4=gLU`T$xj!drj*@D8H6A%H`708c%DK)*%d**up zD-6HB$f_><+M*6t7ng$C;tEz4PhnM&qU(yWSXErcUfTeB>N9@7ypbQ-OFzwxu5u&X zZ0;Ryb~lF`>E?8!++1$7o7>If-s$Fb?{f3Gcf0xBd)xx5R&w~!m-7ItHQHKV@q z>p4}1q%EC4lv$_!GPg=kDjD&M47=P};jGkocJ;4j+D({iw>aCJ9nP*BIafx?oI3BG z_|43F?U%V%M#)?<`cGxxpX6Wn+Fy}@)so-K!I*&`qm1Ujp-?o9A=zmiTA$pbpM}QI zB-(-$q0iIjNojxj0)2s$p)b;x$bIx>+Le^0-RN*qm5!nxkR&>bt|k6H>W-v4OJ?0k zFV>UwCjHs#>`n4Edy5SsL)bfPC>gGwYQE1#FpT#sg{6=ba3LER3)vw%Nrgy=C6k~i z6eshcBvd5}bynY?v-(CoM$6#i`C4++h%h2(lyTlTPji167mbTF+PG|7rnyaY7|mn8 zWe%cun(vtJ(){Ldb0jTfjxs->Ma;406k6PzX3nG)%-QBLTGd=(uA@(w8D<7eGPju9 z=riUHa~Exf`TrViVP41l-$%rY3UschBr4N%tFRSI7g^`mObd^$1;K)v{{QwN`zrK3!)$X+255vl>~A z=z8lJ>pA+p^@8;R-5kO}Io)D6v!A0|?G|<`y4`MVcci=RWILH2!@6NKJ&v`*SM;2H z%DzZ59p*gEgww?7%AR${x_epAaLsT{wj?|#Jc@rU)$1i0jy%)!40{vWGSJMvP2

  • 8U>9)MvPI|h&75BMU7%coKf5;VU#pV8Kvp>bOYT;Gw3F| znQnifTj@5so$jDJ=`OmP?xB0>KDwVCpaa(|8OvsjZwpkJa$9{m=MqNF$}kG@IJZ!WJ%p44wr@vF2}`b`%8yMub- zedJMv_fcLNgZEJ*^zI9^4c;xCXfo|i-=cqS(}8pd-Z8W2Lb`}9qs!@PJ%jWI=Z*g8 ztd&1&!ymXgV>Bd~F`9(35-Z8#Syfg8>ysz3`gqaqZ@*;^um{?M?7{Xs_7FSOo@9S) zPqC-k)9eg;lfA{>YHzc*+q>-D_8xn$y)TI3w_>;-qi;lLKce1JODQrBNu zK^}Kra~~pWFst23-^b(PkZnmE^TdC%ctVkNIlN{?R*?YmuSz(!P7Pw9C+gr8>#=%7 zphuo07J8)-jw70|Cd5Ynv>*=Fj4u)wtHt&tY(Hf`MI?@7dk_!DDnp5~huNb^9vrdE zCI#%d_E#hx$1OjQ1pBmok+i^k{3dw`Gw%@66*KKL(g*YCEHWJP<`(h+w%&gZG8bEL z7x@CS;T|#%+j1ZI65I0tnU8IHh%CT%Jwnp4ZI6+!Fhiao3o%RnKo()9JWUp3w!B7` zU~V+Y8mt$hNCwsjcaxo17sQf-=nIFO#7rGQPGi1|#%lUTzbGH{i~o7_U-zi*$wc%| z_TWkD$9i=c{Li!hvS)AjH1U6CZ~dQV|GGXKb2F|^@tlRaiAv3wwD(mc*K~)~p?lBD%3YtUnt}3bSl_4M;32g-0gp+NBX| zhDUW^UGbO!Y$zMW#0?>GHFEmMXB$x(=NP$slvgarN8=95_0gPQg*7g)q{ej1(|FBN8Z)g3 zjn}PgKH>=E4vm$)tTt>-3lqOL6hRq7i=u2q<8bkv@d74Sg8p%d|SmcJvXH?P(2^9cV3-qv)e3 z$I#j+M;qA*L%ums&N2L%#w!*h44LAcfjl|N1(ty_-7-;Lvjoaa%R+hG3K53faO`4L zrc;pFC}cBLV-tTmO=A-MMB_6wO=DB~sm5k>y2j_|XBwZSGc-1*pKEMEXKHL|-RUFR zlh;SI=q`;5tb7{Nt-Cc|v+`@qwC>S(-74TCT6eF;$}~m$daU;HIPK*RwU@_hFMp){ zJ3;$*qV{;I_VOg{<;mL1AN#(uvTN_;(B6sE-pQ%G6QzH>lS_LiT6-tA_D&w(J08)| z#$S={?w}Xtr?|TEti(9bX$+`|0YzA z8?)*C&@B4t=oWg9>y2yWiEfYDCea;G){1@wWxeQ5DC~wZJd!2v%&Ozs}bJRKRoODh(XI$Z0ZpgJ= z$93JXD_zem;udv_xp8iBw}e~LE#;PW%eeQs@$UU@S+|^9-mTzPbSt?DZe_QM`+%G1 zKIm3;ACj&NODVI-J7jiwQC^alWp0^A-iaP9sApV=o@Fs`WKk2deQVYRGkizZ5wm)C z)}4QZ^@?z*=T1C5Bck-PjR^P*J|o%8PtED%4s(t9=M&8E4?0^g!`E`QIorsiI?vbEdHyk-=j-S^Usvb(dOFWPuJe3- zo#&s>dA@jj-NbQiH5SnMm^9-v58z zi+{U6X7wHa-o>6$gVoG>YJe?#b98R+w-5Y$7W38&CbmYT|8z&&4)mNa)r*eB(a#pKW0uu8Wnxo2;?#XAUfr+Cs&cBl zs-zxNRnL%;mK>l&lP^XNL5h6r2^*x}PsTSy&=T&QBsy6B+Vyl-` zd$jfy^$PJ+C-o{(>NWKm$)UQdo+MKBR((h=)mQZ;xm7>apX5=4)Ch8y8l`_Gkisez z{aMCevx97F;cwJdwNYD7Jx*fP6Y2?4R5emfNHO&cdaI-ws0NZ!+S;O8`mF$@8-Awa z_bI`uroW5T{#)k$E><%7r4*v}d(SI}h{Wr(@Z+w5tZvul5wb7-5Rw9V1l=G^LS^)|_S)AEnBmJ?PQj=s|zS`}@(q{7$^(eWrJ+ z+`6a!n%?{K*7~dO+~029e#C!=`G2-vx@A{GE&J$-qCe?F{I?8s`wv$Xx2&o63!Ac5 zkNtPqgQ%Y8 zZ^(iNz3A`X68<|S{=O~Y&x7dqdMJO7&aIgS|J{gO4I(^T1}*k$psZ&l(YgkKtoa13 z%{oJ=$B^OUs*aX*efhiR`0p~!j_3F@8U9&WST_rAw*i>R-Dn@$pAM$OQ~|WQfVvmuy{aI}f~pY8LMjGjj4F(>u!=<)tBRm3g8pQxs49lC zn2JLgr;4L2u1bHPETKxGEU8MNETu}LEUmE3R2lR$^Ji30#;f~L-ml7{EUU0q@@H63 zmRA)}R!|jDR#cTxR#FKl6I5lCl~om#Rn!A0A5e)X6V-z#A5>VS`aVYK`jsGc65KCWBu36y_Ns75Fosi#psts0|jjD3o! zCfKJK_N;*@2i~@?IV+2OLT)_w`{(-Rt$ye4YcuiANFvO5!_`gYV=A`AL4BXBwsDd?RXL1gj$OSOMvwSRw$X#W<|{*6QbHYKHW+$p2uPFWpy zD(bkCpySR1I_@Ouxbv`%JJogEsj1`6qdM-?#ugeu>gu@DSjQc#Ie8TFEP$Aw$M87B zqP!F@ix|%<@o$p25jb1&D zc$A;w=Mm5H%LYNrG`L|CFf88Sl*~&R70$4 z)G#nYVT;r^8X-2sc4>~-%xGn_MQmeqFuH#rCL7%h%nL>@Y%RPui~+_FV+7(bW0Wxt zF~yi*OhKG%q!}|2XBcyhbj10_Vq*p3GGn!|9&w$KVQfd-YV0-+BJMYi8mACX8fT5m zh!>4alM^tRX_*qyHM5yGDl{X_JZ65xd}cwjC}ONx!i+~OW0p6oASReq%^HZ+&Dwuv zeZ+cZLo*4nvDwUQh1k+;V|GAnXC|B75WAYa%zlV{%>m{R#KGn;a}?r8GsT>MINqFW zrXfxL!>hl-IR1#yfRFD4_VifLj7;&d@v%txFj z7K&wvOT{X&4sngxAhsfI7CXg$#J%FMIEi@N--U&EUR<>p0gG6s|18_GEoFa2B4)Ru z{U@qcUaNo=ix^|YS!EDQS!JyR#EMp;g`-5PnpMlHhgipIU^PZ;WHq%~A~v^LTkR0r zS{<#fh+V86R$s(ER)1?S;y`PtH4<@zHO3l`IL=D7rXfzTrdzWSXIk^Dg^20aQfn3B z3TutE0dc*x+1iP?-P&s%Mm&FL9kk*;lsAO; ze<*(_CWQBYsA#BEs4T`LjM%;mm(jAcpHDG{7w|P&miBWiYVOsVd$p#Z))ds5f?88Z zYYJ&iA+3qgni#E#(VD_qQ&?*XYfY@y#A;2f))dj2B3e^KYl>=3QLTR|sx`&5rkK_g z)0#M~iPM@mttqZG#kHom)|Aki5?WJ2Yf5TONv$cVHKnwsl-88en$lWRT5C#cO&P5z zqcvr;=02^tPiyYens}{=*P3{(xnFDU*P8parmWVK)ta(eQ%-BjX-zq;DX%rhc5fKr|IV?FR34(xf9)?r0sAO0K1O$moPJ)Vyt*)u1CgunWG z^B!*r#}d4S|GYh$-fw4mDs-r-uIT|%9Y}Q`)q&IiQUgd0AT@u1)C5u!$ZbGw19BUX zT0m+6sRiVAAh!d#9Y}2;wSm+IatDw*fZPG34v;!P>HxVD$elp$1X34BT_AOV+y&$= zAa?<&2c#a5dO+#}sSl(+kcL1S0%-`O5s*ee8UbknqzRBFKw1K638W>ERzO+-X$7P; zkk&w218D=K4Um5}K-vLm2c#X4_CVSLX%8e3NFtC#ARU2p1kw>mCm@}GbOO>DNM|6O zfpi7Z6-ZYg-GFoh(hW#=Al-p<2hsyb4K zApL;!2htx%e;@;a32Xa4< z;XsB184hFwkP$#e02v8nB#@CnMgbWGWE7BxfII}`At0lHj0Q3q$iqM$2J$eFF+j!u z83W`IAddif1jwU69tH9!kSBmV0ptlFPXc)o$df?E0vQWrERbUAaj7s1u_@NTp&q6 zl7J)unFnMZka zAWMKO0kQh2NL{;$ybsefl4X80Sr`FWoWQnk6U!VOw<1w4aiHR(mQ(7uf=xq#hUc5Oc&E#9u zr0^ToX5S&ScUA9-q62qxdAA=UfalLGmL-3i5~&OIq5*hEdo+!q$7w9$GSg``&7+01 zgjUcRTJL|c%Z_W$zG%m|PH~;t8|@a?!+4|Yi}qtrba32|xck`)9T_*u_@8lR=Z{wg zv>w0{0(eRQZ-a++2F;Ggqh#TW2Rw7}vnP{<|E7@nHmdn1s`(ab0C6G<|IH_pRT6)L zs1f%L6MHoC1^dp^P)Q)aRpIfN~+q=TR;}`2wz7iu!Vt zD^RXPxeDcKlxuKhGU{tlu0y#V(XqPnl{-!)1#;{fzU=9tnaAAK6F17XM zJa3x}l%eV5--0`nAL=@vap0@0E(zsy!NJtNR>R!P=Z!IxqC} ztJ7MTwwe(sR)y7YrPN)m_QHSk)#6?k?)}w}6>_B%UcDB>H0H$|8eT6`=7&U&vj!{? zGk(tW*2~X3iEj7Y=hyg)o_}t;W*ihos|o%)V9O}9duOh^4dopuN2ahqdi(o5i(sQJ zHkKz^t4l`4=5)L+{%mdXYcHIU9GdIy@_EPvip|$kGx?d%XY!syInRF`xy%lW)YzlF z%nHWq*NnJXaY?*JEsR^sR#*&H8#B7hic>!oRQ%`XWni0^SIxNR;}*p&W*acX=V+hL z_J0AN7vs=SHpAz$rO#)bE8z2N4$rio_I!4|s`~7D&FVAhFV<($HNt1FtE$gl*Q`Dl z{>A!Sc#ZHm_%G&j@HKzJ=Ze3W&lT4QpWUwN`0RGgj?ejju|DS`V^r{u`KEI%BG^}# z{+`zj7r3LYPf>akL5kZDw=r&$i8hgWr{CC;wS9YT`CszXPz1}!&14&yZ_^svFr%p< z->9{pW8|_o@h(l}pVvXnifbSf=JMXQtB#)0(eG7*;s$e{n(2S{sTKe4xGj+iZf%M| z)a;pSh}ZD@i}zl)^q08K=?}^Op6izW64yEXA^A7BZs{*^ozs6i%0|~M{k5)h`fI0x zezV^es6tAayye?3U8Q_1>% zV*!~fg7*g>4L*OahNyq2WVKG;Z0xZN<^)PB_|M>zkWx;{!d7M_oXA+08cuQBV|wU1d(#4&eRF0Ny||HgXq4)XaA_%>HTye+TzrdYr~%@AL_Z z#ct|UnvE}R%*MXye8IMua6~&U<3%&nJD}bi^-f&o5G{XDZwtI7>g`c)g?dL^W9}8W zOX7NkD>bgMMQbh#;#onFhL;V4Mqe>?V|vAe-o`FTXTC+U(nNtn-w+872o7frJ_ABuNjAy>fH z+*K;?vx0vQ8C?ax3Z5qNZujmc&r9}_DFGIKCG4x1(QxIhrQ~PTMOumpwh6Wmb^u3J zQgD>oI}IIg2ESxFs(Q7Ujy2vIpR20;6V26?wwR9lzxgQ-EBWfQnNnJ-FRJ~v!FG^U zY2;a`RNZ&}XPZ81iGbf)!>HEQT%@(w6o2En!~cJqm;e?_9y8FzoRIcFK;JV=Y;D+GF;HKc_;FjRl;I`oQ;7h?B!JWaEgRcZ%4ekoQ z7ToQX^U8ZSc@?~hUL~)xSH-&-ts0I9+-3$x%5QZ*aA5Gh;Gp2(;E>=@o-c<5hx1kc z432*ZKEnJz7JNMTuiz8GC;6UYUU9F4SJErxmG;VbX0I~9H0@?u%keW*Xckag)Fx%# zK8sN=sO{<{3RpYnW6@Xi6aB>iF;Ltm28qF9h!`r?igjYW*dR8FO=7dyBDRWcV!L=r z><~M}%it=*Qc5KY$Qxxr zSx6R^MPyM~Ocs|VWJy^{mX>8?S$VsxE$@(Zm zF8P}LMt&>*Ex(iB%OB*A@+bMT{6z&+j7q0sReE)ss-TXqE z-J=?)dsRc#NHtbXR8!Sb^;7-T05wqErv|CPykz-_ zEnCa$+O*xms_SF0M=I(z>Fqo4*-UnzhVmcsQEDTn$(htqE|x2(tK5Gr_fTK? zt2{#Ys|+fhMyh728BJ8JR0o>G>+&#~svc3}Xr@}MmeK;XL2abP+=sSMsP`;YJJnu# zQGKP3&^BF67o&G|30;!j(`9s7+UsrfHq(CZRqs{$z&x!eBfmnYio)?S6VzETLAeM?{;zhAstPm^3DzRFu5y|3b@r(FX z{3d=Ee~2UEs5mB$i$BE)aZ;QTrzJ^C24rv9NA{KdWPdq84wU!FL2|GhBFD+`a)O*F zC&|e&NzRkc$@y}F+$cB6&2o#}D!0k)@?-gl{8S#6pUKbV7xGK_mHdBNo|LELX+_FX zrBrEEMwM0NRC#ris-P;WN~*G|qHb1I)h();x>Z$IHB?R2LUmU?R8Q4Q^;UgUUo}cS zs2)|!8EU4QrDm%+YNcAGR;x8Slg_NO=&U-MzCmZ#aXP4lmRf18ZS81R zd-^6_!Q1Y=7Xk0_fg`nlK&~hbcxhk|=3tFxZEjNOeyF$y| zpyj^M@<3?$0ci67@WnRR{DAzE5?cOV#K|5R9xSe zFBl*|un;`B1-IZ1!5xA-BxrDVxdDP(3U_yRhk`(GcXxLvTwi^E-P5n%{4w)huQfeu z?W!&JoO`R*Ik#?|eLj0{|0G)K(1A@lRtW*742-d`VxyEKX0woFql6@;-H_%@i&*(MVpAF@@*kvc%Dtd}^IOoAG*C9#KPEkzY2 zsRR`yUn!@hISmxPV$FQw)E3MyC@P#`w@mg_7S7Tr$~{ctt9VhPnU;ZquxIm_h{sv^ z(xYY$ToBTg6Q_3CnN~IIQX7}NhP=j>0EK zLWczL{C9` zUNN%Jnj*1ZN(5wxO-6Xr#vmKQwjJuYNj=C!A0`{8w9Htd;;XE%EXy6nFHTJV=@j$2 zD5QwxG}|bLe5s$REq4{EWH&u5n(DYK90sEU5anpbXf;3acp>r3<#leE=i7=rf8fEs zg>T|^rrfMvNu2Bsk`1ZJmZzqW6TLEjj~JGH=fyWwa+>?N*%*pFxQc4ZU@gra`c|C# zoJb*kz$gjTkk-4Pw_e=vE>CWXGQ99Ee4?Nl%}EsodHqx7PhPrSQ=1SNW=NJ-bE@(h z;Qt^w&7IwWb8SMJ;x(F&R#xgJo+nyCt374S^Jmf5 z-l>ZMZdi%C$3k1xoZ%Kxb}MM?Yv}KQ2D8j&M6VH_fai!lV(-s)diEVli#BlJB4Hgp z*U_bc)Ms$bHPM8rNJZj@89J7uT&(!psG4QM2e)3ShZo!*6tv?V`$V9xZ7kVNuePpA zy}8lBmC~)OYYW3aCKKKtu^8-T{T!x(DD!C>Xk^J>nrTPY3?9}{{~ge=rj%&_z8w8F z8mfiiwRYhuAhLGi%3rqLIL;F|#JQ&5QE#2`itC(R7NR#h=A|EZS+zR@p*waHTsgHFCwxE(?e-uDy?bYJ!E$|2`$2T4t zHskM|FYmSF@D}yc&DZd`^AQf6b0Qh<)I2>-xx_PHbgf z#lDby!gzz`I*!{=Q*W~rMQpd%09m|0hP{b&6=|)~pJq10Ym{3sJ#oAN6kOq3bMyxq zl|*NEy{xTHZ{NEkwnw*#t@f?btQM|*KVv_0>Y*B5P9;1emVePToNMb4wF^yhqayix zYcy%=qZy);(qu02!cBSXelsx7#2@e5Ikmotyd>xn*IQka0u@NhgXyf9XJ~I*TUNz|GWKQFaeJkPjSRhRL60D> zL7S#RZz!{CDkMa^RqMA`l0dyx8@5-Xg0d0&F(uCDf_h<1wOg-fTnABPU1$O+3I8VL zI2;^tQ)LNYnW7||UqauZ@dw!{4zUEyn71$;!_xVR1p0*B6|N73FNfCzbuYtEwW)}; zwzmxY@`*LhToC-ko3V0|8N)`yO(!_U?^_bF5umX0Ovht6yx(FAiMF3IV^oW=ybnmA zL0trBU!7(s2zu3svVnc~hRwO8JA(H7;De2;C|_w{EdMsGFn#N)HFajhvfdtw_$*JT zun(LWbkUo$JlS=1(zRLfwiPN(hwcDd)VmF}n3lgkRj`F;m?%HiXy9vBUn$WrZ*0-+ zKHQvjw9;N#=3nO1aBIw88azBWxpdWr2C=Oglt$ln-1^OM3(0xomI7+8rM}uR>!rzu z$MOJ^>Y($k@xvfNOHxTm5J5rU!DqD|bHC-IJ0a$*6H?;vTG4W*WaUlKP>(v&llO2 zq#o=Z`>=98z<^II&*fyLbjAp9Z1nydJ#hdAeG1b|{Xn<`V~fyjga?RA)Gi(Qn2Ad& zT!a;OqP*}s6Qico44s0q14#o+1R~zSj#tr}rD4PMCpJ0iL4zMu`bm}$RE9TT{x9m~ zzt<*Lmzc{d;IjYCLwn5m1d$ncbqkA~)E^?E6rfDg2Lx_Po zm2%NKOw8~w<(d)W+d8j>_7fpj!`94|HIi@Wb!W9w^XQAYC&4GIHrPY2X^a#!C4z-RN(w zw{DABA^j+4>~&JeurZKS{LY6}Ea?m!>w&N1!R2$%s2jn#))!r+xtt798m?f?bItD( zZa9Jx0Be8Gfx9B%(8H!jWd2>9dy3KU%Ns*>{o$M|qbTW|VKZFg6($Th+Ey)k4dt|j z$M4}2!x$t(_OL5PCekxnzN*DRAkvv%f)4y+F;c}0LlfIcn|aG1p9CT86Uj$c=gxcuNXdpYrg@}GT#=7|Lg1&1KB zG6|af^z((UBgXWlCyP|a^fx1}>W?I?fh)bXM@xw44_uwjUd`q*uZP2qxI8R; z1EU&y>U+d{Ka~65IdL? zJda>0YwXT=os)0@vsWi(EC z1rBR5+HVLE9GK%BnC^dn9Ai)6mU4dFeJxX~xLpOkW$+o$zDH~Ob72{@{HCEw%*yxX z^*56Jy6{a@W5gUv=K{iUmdj#v|Eb%NbHLBk9g8YpnqU z)#|muDK+{|Z`Ob-t#pe~+`}!Oe#lW? zc*BKa$zoMi#n)+1gEwh^i-^JmN!k_d3jREBKI6vA&y*nRl8JV=dMovglW=n+Cv);9 z4T=WOWH<7)5FV9hP^SAkb6?GFz$yugeNX>=tj?uA38n@_&c<7ds(cnP)Fz?ubQ8Pd zJg*pA2+>%!jsZ#~{L1O|#l!j%UU4-V>NEOXLzkDg(s(p0TXx<&W{A1ZUW`Y-SvVP~ z$0fD4-=?X$2g***sHW|)_fBl&g0cM1z9d6#6JM15y(=d*J(h8lqF<132*XrsMl&-M z6*h@;jsskBD!lKEqHUR?u1KP*X-&_}H!Vwgs>(Y1iP~bk*8+yHI|-xm&rx5>ap0Ub6(`JNq1HBDh!C-cXs6C*H1rHv@49B zTEkyQbv|`M;0+jyz_aqk7Pgo&46A-NngzwTG2_O2?aZl3knCJn3f(ZIlx|pZxO}&A ze-B(M4^1O`ekII=ja> zqIHBqseB}tP+Zl)HCgBT&4X`NiBWazVWEHKA&^RU{9&Yjnr~Fa#w7jQ09Uml!GTVp zR!1ldTMSyB`GPB&iOIbyx(OTGdlNG{^!I>?Y3pO`Px~m|KDfw*hDD4Yg9alyxgGL<=^Aqd>_Js#8RdMA7e&9W~fM9?_aG|#(&iy@9!Kom&cX9o5V=CNl2Nk?Gcz_1yD>3*l?lcGZoGttZ^a+zYwD*s9f8?d=lcF>rela3giR z0YFR70hWOI>$le*ua>W7uir_lqZj|d`pS^-X5;4w5bxpV*q4}&lhe<+hb4^|yHXgH z^i9hcwC+{k?A4y)9qv^o0a)Ele=E$^Ea&Qu7H;Qn7Zpy-LM-&?_B0o*9J^C_ro5O= z+Xc_Ps7aK~?DBpu5P$ao1p0ExcAm2*lIOr)hM!dGbjlr;()$`YG`V}~sZXKhETWAH z7{hpL=y&@YJTvt}F+CI)Mfpdp#SK&NLpsC+t`U1w0e?di0Y%3sJ}F9}P~L2YC=$hu z`fDx&!l(MS^SQ82!&3jpl0R0h@CLdr?lzpG%b{Kzrvs5*veg*?gEIc|)Q4M+E-*xXn);~3k-M{a9Q7uvtbao@d~2yQZwH+ zPfG7mDdP zWfDYl*o9Tz)$S;`62K$M-dZRasRL=^lTh+p^AsLeIdeOEw@TQi*HW?9k*Ly2su$?s zaZhB@)SoV?iR&?Kw1daQ;?<;`DGnz7G{ z*y;Iz+;5r8CE6bILOe(}UDi34^a9gT)4kH7K=ZeSqujkgPD}R!Dd|7cgrZ4Bs24eT zkrO@}GNBX!7dL_+ZGk6^eR7B!@o8+u$yxE+- z_*6nD=IY2+ak#t)&FrW$!fHpvfAmQ%ME*H*)T-$Ov~9F411yw%%A=}h9jjbP5c7BW z>o}7~bCNpDi8|N5}7{64doP%6w27_M!B&G4e=_y2mF}1do?5W zsc+fJcc-V{CTOD`d@gB3*{YTe0bRRhBS{%foM*W>=m#|0PeAR~;oCzqUgC z-*agna6B{nubO_oUh%w?zj@XDooPreBs6L3owsr)-D>mXx^#EaaIwVM&hzv#j4gd_ zPhb`#M1@;CU>TImKF02rdWU)$Q}ovCTqUV%=o zC@ppkc4_-CqB3;-Ih z;{zGK@fugDzSog=?D3GF*^N3qB#+3m>dNX&IBtddxSp~pV1$vs>eojhyLMlkkkq#b z3V2N$ZW{MB!@n)%*>W!|>k{6+5Vj7;Z1R#Iq0Ey;_z4%Sqwo3)YhenRSls>ISr92FY3GA}`*>17|YP`lLoI zue5Yqd$DH1YZPP0DPI+9tuXm)_Aw70(Nab%T!Yjt)MK|z>n`})n#bv|c-XgN7T>k= zo+AoO;v_no|5zsNlCPIcom!sEZ*prQQG|6HaLRDQ9%HB3k(7#nxmC!8^f|Ppgj4^K9Wb6i<>f)sY10OT#1FWb?j5>Zzob% z{tGTnRsI9kU2%|xoHvEg_n|$!3zQpGOuF=ACNI@8Z+W5Kqh21~D8R-~+Y#3^PKGVi zCL!LD$~1v+8)1+ldcZhN9h!xN7P_P1IF42lM=!CU?lj}Ssg@)A>HDVcrx|*>?3;g1P5w+L^e=Y?`JB z97yu&s{9_$an(#hB(Pxn*{g2hJLGRV7J%N4XrYKc@+)>DXEe|_mDAhB>Ge=mZ`W96 z#2o1v(-%{YB9yAik5@Qw1#y?72CiDZy(l5r)dJ0Mc;?+MZJo~E?hGG`6J|Ik|NByx z&zHjwFYF5Pf_pmxQ^LVCy@neKLFPhfDVBhts#@r@-~Gi50nHl-Oe5 z4MUR`K%X}20bM#y6`KyXR+yELzTS`xPF0vrzJ~_AZTwD6nR@7uEUs6tybTkxm9|TB znHA@Hjo(b%5Ky3D#jL9vsz>?~b(d zHrw~@^>Y!a#PgfOzOMl3^;Qw^^C7bc2zfx7M$hrZycR3UlzjG5y{*Z5fjiVzetqkL za@}3jm-WJXSX~78d3sKR#RcIG*RnDurrU>UQ8q&jv!8Hx+-QaW#=|UM;~yU6RJ^|1 znJehI1K13W^+Qx^tiH3OtA&5Dada#)TPRK!ooYS(@c0z_*5Vf5t%QFneP`5l zuO)m1Z`t(J(JempxI&^Mg%`w-rccV--p^JJz%Q$3Tm;^y)UuBvTMh>%d3 zU-ofJDTBCtm?+r_k&>qtK)m|z+c-paoe53)T%gR&o>d?$oZVwxx6(=o^<>w??<>O4 z-zOUb!4WoYUgqjJ*laWqwS*v*=*&`c`QlwR+lcRluP-7moA88d#1o= zM}rKJj#KCDqfzmWQzy?%pD^5{2<;;qlVN0&VS1C{UP@yw8a6X0C}UwW!%~snk>`S- z0Yf`wt40*7@IJ+Pg-%ZXOkqxdGvEri0B+Gueapftv8Qxnm#_w9iCshcrZ+X>y}k3& z{L7aBlbt*B%pS%o;o=B#0VJm6s@EzwA9N0(wtZ7&pQ%hs#@ot~jkN`rREP zwkF)wsY^B|H?BD=6Q?F_4XyLgIBvkh)$wqfaPZqp6ctgXB~s%PIzBM`3OFXH3T~E< z`3#t@UzYYS{n@w`74DUp*iHN4BzhISX`W_{B{bI?lWt4 z3&++XLLSt&G|;$he@&E2qc&#)PZlf+Kgtnbi!7hGQ_YO>M_T;?gJ9t3j6&zT%&p+- zg0g_GsJXC2`jc~)Y9=#v;gAr{Va`)?@%lMzd(>lEXl4iT0pJ4T=+2eV!_|w;8pzbN zV8rE$jDBJ5rk0VFHJB|MGs5M`O+Pq0BTe58xpr>}-8&9d>l$8C1DT&1t7$_s0S%bI zuE}ykj&);8AgFrLmgkJ#=rh~NcLpsZ!@X+ZP`HX(>fSb&GvX>)d3VDctEJC?({W%E zV}#x>17%|d!1#`lq`@m?OOV=WRcFwp|BhV$ndCz~wZ6MTGZ{RcVrCs%!S{yU0Hg2+ zyqi&#$vC=^A1X!>?kdOFl|#5S^+eQC{ZiYtmkP~NzBB+xO3m}SNcNJ;lYcCm*NMQ4 zT!`90U8yAS5Z$GxXQbWdcp*cK5Aj6rzdj^FLH;W53kq+AF{`PhM9h@HW-84Cezr>Tsdp1yMb5q z1rP3VffG@$2^i-W7|LWJZs$Lp_nA1Hj1ZL^mSY(0Paei6<$ z9Iy0&7LzHwGwNunOsLFYS(zK28=RY+>zZ4b8{+Qdo=@Bvy2iPqzN3CDxHo$^y=6N0 z=x|(fT%%v(TSHi*USsIs_Tl$#^+EIw_LlPL1ANx{)heiix08qxtp;3n5FCx0o0ny6 znHm%M2UfO)F28sbrBUMb$8OVI%6mi!D7kL`y=3zUY}4_TTqU!MF$6XCFYT;c!rU9* zqudjMkCh<7PbuI6a056)7@Bo-ZFy~QZFa3|ZDFl@ZA^GR^JMHI`daB+=|<^x>|*Q| z@OlY;j(*U5n7ik`GrR=vuAQ!(2(Jro3m*&bzVdx}>Vx(BqC^ z3bZ;DXH;jTE95H_RI_2^?YF%MVX%Mw==|_uP?mDYs)=DyV8db25lPU>P|MH+@Z4F? z9oOqSZ#q{y5&gRTw*0W@9A)dVsi+b#0j1)274Ccy+1R)QIvZ8K0%y5{L`N@K*TMZb ziUt?FDkitI`saAx9Zg8klKT<}H|p4-0N_X}L7uqWRoU>-G%1J~RCM#Ar2DEbAF8MxvhswA+R*{avw+3NtecLab{5OC@MXr& z=tPJu-{|_S&KNBJGnoq#IaN8}B_Upxub|uPn=hk`euG?_H!po&vq?JR8lGFzLSBX1 zh&mf8qp@^d-xS1!&?#-K*k9N(Pb&8cQtX(nh2`7f$gPFZQ5g-Yx^wHbrG|3=)mP<4 z2Y$T-_7pt$!?5=ltRI@2*FRN#bpC>#hL+%`R2!qMU1UK9ttCY^{rMdyswi5(*Y1DB z<{t0ZP9uAyChULOwFQaf{6pmPb7EDM!DQSh!*G3m%v#8oK7!)MN90C^=opWlA^$pB z%!_S`F0mj6N`>DA{6cy4s<5|B(Q*D0Nh}=8V@Gck?a+A)1_Fnh! zQSN~6$|9>poTSO=da;C2`i(AWwIwph2`|9M>Dy$y@=y#P|$L81m&t@~rZ2 zRA`EWIld6k?`#gd5i-LPNjo6hl%F%HcjW>EHFV95dE`tJ*jjtAmE`d=;!5urrSiJP z`6Tk3#Q7Gst(?OL#*!MVYVc}y>_iqq=`xbo1n4v`w4JuO}TwpJLu{5!=%-2Og+Zv%YK5TBi&vwG_Ju*|#V(*QJf&_A>N z$s0uHNtV3tXR=xLJG9i3`rni=5^3s+i{u={nE&hOaY`tObOE#-l9^u{PN*Id55jhN zKW2HqC_~M77-Jm;%D+T$2F!YMd>o4$9PJ+xxH_Of4UF|fs0bvH+s_<;fqfH%!z;N<#E!SbEBv1RZ%3UIi0~^ zxn~+7#$uEP>W7r42Xk#_1F^xr<3AD@db|UZDnCFXduMz&b_pYW$3I?~^oC>%f0U=g zP|f($y0N*Umlq1vCt~r#^ZUZ``;25mlPtRUFwuRjTpzlyVx-z_{gBcU5Tm|&z9$(OU2{_hv z0s@~|gHaOv+m0`C{xgxr(Rm6a=k&#fk|-r4rBD@^eYfn`N5pwDdd_m3K&P)fMvM>l z{pw*VT+~)WssKl>d!KA3(D+#AAyBbJC>UD* zr^4Ho;Zw(vYKiwB@ZOk2XsFWI^Xgt+z#2Cn#S$CL0*JUYv4m z|8mE)#!#tBBiyG2?+=d+nv=KDdoSBNnJos{nI7%)xPmt2qJXf&L1BgJo%xz3)<~Xh$^g@c~D3Z?6$6krpc*6~=vUto&aX^sufn z?^C`#(a*iz0?fhGN#IZ`|NC%5tWEGGC;1DC0hZ;HSp^cOZ#G{n#i-2Fz_-Cu4LNOs z&#w41!{obPYeQC$AWrr2E!AG*ioae-7$q@TKY}ZL>S}xhCpsp6tYKR#L@d(e)Lpo< zt3>p@jhl`ZXX2C*bOo#H)*ZBwCh=b!-Gt3%Dq&Ju0&;l-(Qw0k_#Cr@V+3P_EFm$v zv1WOK6suH=ug1CMkjto;*op1l*swc~wz|c#_-p!{R~fvg^<_HiQZ&=07IgfPhK+YB z7le{X?_XG!9MF03_n7hYpjZvvY2DPkTCQ1YCM{hFY@OnSqWiwY=op;5U&~4au@c92 z9Lb8*07#TAl~LOB_VZ>N=WFOJ4Mw*eOT*UndVd}+HO2i38nY;Wb7Y+GMDLo#SeOQ0 zOq9tR-8Ji*IscOZ*KHkF=aq~r=0u;2c>+Lskw94D1bKj*WNFc9eoae7d>2H=$Q@u( z?ai9X@?5x}qFhI(gDe!vg(hc7dShfgbx_U$+=Odz88elPMU;(2h0OBQ9Mw{`VGK3m z=@#4!FhPW8aZL-#%tp`G%Hlr*3Ef!|_OzfajpsNLwEGMVbfNHuM&ok3KM@vx$_^!v z*Oj^CWw)Djak%u8Os16Pf_g%*Lk&0O=o2*U`129%R~K zg}5bdA6~rn9IF4!6IbWVuT;m(3s%z|s^_5kBC4=stcgER7Jnp9m?MSp;F$XIvoR(p z@z>Db_}EOD)X>HIMn&JXz77^7r0Dn2G{qYh8wa1vX1NKmR`g6OMAg31wY_Dme2P>o z9rW?#GCiL-xj)kRliQbOL+9&irr37Z1hg=XwGfe{*Kf`wNK@P#EX0XdnKCr6f|wsz zcsK0S@!1f*uE}kd7k5Q%BAKuy2O0K_;en$K zWoBdc`op(PpH$j6H4iu44pdTlq5}!a03K{Gp6rvEiJ@BfY^VWAyHJbJgT@sP;0q_r z*+AVOb5gdN5~U0qNm#C`rF}zQ(QMe^ndV^TVLh4c5Hn}Vr&Y^MMw*Eax!$ATcljY{;p~TG2US=3 zSM^uK*HdI@%JIDxHacT-tHSd@D^MgnB)lj*YnU~yV#(kV*CH#J-!Tb%kmpn;$hx1 zoB29aPm~i8uPNUv*AxXORj+(Slg!ME_=mz077f`MO~{mCu@z9#p;d0~ThF^Q6IEY+ z$gp*#dAL!+(!jh1K~^k%Fgnt^o_Un7TsKxXv}REELF+u)eq2)WFs;$NxovYCyF$(= zdXPm)zhqPLn5lTcJWBk*BKyrtINd;!#ki4UeJ zCH|?=PhVQcnLh!6H+h0GoQuIX7nOqN!=(N~H{(5d@6`FiS zioF6wg>*5|VvWOqJhQ`?>6tvm!^P=6nc8U}&sS0>pF~DbG3ad{VqpxZYjWLM1v`z@ zJ5K&RGrEw(E#{5KTf+_H*cJ`p6rPNlZ_xaZA*|{yE{~b)UzwC2h}o6PP-BMH{*0TI9g|^^Ws$3t z(alev^gVz(P(467u#)}pvtZ&K=l*@&`|`0HBX(Esx`Go6n#D+Bc({YFeEv}dfzFsr z*;5CAwWqND&%)&dXlh~Nl`q^An)I1Y{Nm_S##gEIW6d+yoadZ3oR!{_<-wJt8K;96 zk=Ho)VLqzf?A}h^5br3vYP)2+K)d=g{58onxsDO{S)0l;vZJnZ^A*MZnl$=g6NL)8 zxrC#E14pdpK=1Np#Zy{0kk6_o2EZ@$Kq0cA?CjEu>{Ol8&uWaDUa-e zT;1CIHSw#aqfC)k5q~qsG|hBoUa&11+NVgd05LJ?*so@^sT}B$?;<}jiRFrVtrc zfk82r-}0i*Gh-INo`>(Hs+ip|w9wl=mZ2NKa=l@JpXv(wMtROw#p=#G|JE9r3$F4_ zYJjFcQ)g*s!urfNhI4{*opZh_&UplD6a(}IIJ-AX0o?w?ovEEs-)O2(=5dbS-@rWj zKX<;Ym#=@Z|Ljia&d>99_-$?H_itQ0utWe-6s%L1fIVswI_}S{PSNxC_5wT@X>V7N zR^b&9|789P=OZ8w&sk zJMnlHnlE$CtIxsRecgtE;PZIW@)`Z-zUWqBc07Cde-vG4&*V08PMVD`Gdp{cf2OTWw=xLTffIHw=TGK zuXPc7_B;AJf;+w@cyBmwEN_%$WLvn#0J{Kwo{|6ipaG8z)-0}?sJ^hi$i4_92+=>K zy2iR#I$3zTbGumAwLX(FzUhNHV2HnA@Q|b-B=}G9jy$YWeSDWFBx=GwZ9DO^3@2mbqt4b^6(XyVqa9<*Si*S9)OQrCy zmxj|FBnF_*Ff<+Bqk`-~KAypwR~@()sQisBj_@WC=o)fo={Kgq&*Lk0(`olkD^~^y zh*B6+1U@Zsxcnmb!}73-1d|EFv|*{96T<*zF$&3O3Dqj@zv?#V!D4wJ#xm14VCn>; z=ufva#?g?MPpOjK9!;s@s6FDVeP_g2Yw8I5nm|89c@+0|Dyroj>cTl83^ZlMiZrLc zfaAw#LNoEmq-=te?*tCHLCRA+(S7gPEeY`muOsCm5PI_^#d1Lo_|ZhrjN2DQ-v!J* zMt|(x3dH9oAdX0li0U1Yq@nEIw_Y}KW^Ex@i8z%+&n=u7+9yWuQQe%`oY^YAsJr8J zpaOht1+dZkC@=OaZ=Uoib6y&aU%vH_UW18c`k%O}X%=Qrf&}rSuKElt!|a@C*10z~ zNTbg?ci+Fd3w+c_5jE+l<}HEnOtbZpwec*{E_^)w!h=qI-t2Kq$Xa6h*KTTo#!0$$ z@ZEd6+E0`Jt&r)JIgmSg5!{B~wMS)M~o^ zaO#lHrTrn|q3j{;p{+&4M^iAXqmV?+@avkU@K<3qbZ9OM8kq@lAx-d?Um=l)h9l{_ z%n{wpAlG zD|^b=X&5GJZ)5S&yYF5H#Jf|>E~KD^SwYE?+LMOV74q6K4~3$U%8vB7HBcNtLkDJ{ z1M|~?p#nD@n1$}uK;`9|%FA=!6QayLdhBIz%q1z+j`VSP{FXZ;aXERXy&|9k&3&OTjxPyi4I@AO&k- zTdLNDjHfsv<3~0!I%_)(f%cWKlZmjxMyEVj-<59&#FW2y!KqK=1KBndE6kIP5-nnR zXK9;@%%D@;0}{|F&Oryj&Rsoe96Ffh0SuehDfeG3?4k>2g zH0zVMDu&~?e2@-UaA4P=H6%P%ey z>jV2#C=pKK#=Q#Xf2*g%gK(sDWO+6EzJ&NQ4)ATmf1EoXuAz!i2h9sR>S zDH3L(&JEI}mBKPSK-M&;#i;;kEAduZMI=4w>8(rC3fd?w7cnL!A;_ z@iGc3Ivr(sRgWGDr|9On<-Ukw$g^h2VChJ-o|S$20+8@S+w@mv%A&{O{UW>$(+Rqc z&53Av)Qwbmg)7G9%k&)c1OeHDQg_~+utL3=0K)I)HSalrp9$*X5FHW^ff|ZSaTC++ zf&P;I!~T@{rzB!0qY52;=noVnnna8d+J!^cUD7wg5wMY36~d>I)qF*bGYz?EFDU+6 z%_T*r1W?pGQ#UWVEoPt5KD4fvPdC0)R<B+F)Il36{yD1H7Z_Yq=|ghkVbL)vtDWh6UWSEOV**3fE>2IG#?=vhDB;XPJi# zhv4av!_tB4L;Mi|H_~>w+1X&B&^monw2l@op7A#^9+~5_JI9b`@y9mCJZ25W=MKI!)JXrke-oOqpXn@@Sqh<% zP>hOAzuO*r5O{|15t1R<`X$>ppczluaaklSK%iw+9yzPgYG75kl2t!vJI(il+k&`0 zwO-LYA|SpJ=f_r^=*jzXX~If{acaxhI{pRxwp!QlS&5?(m#G%YUX^OsL@w=CK$l_S z6oa+av%1!sw7hZ_eeXfH-fuB0Z{Ijs2RFxZrF3Ncv>TdJOru~#CajWE$?Fa4V9eHU zk3~@%(9Q1#E!~`WE4ljMdhm~-I;juo*3CCf4X~_(8S-H&H+2mavUxRlb&-pP^?3DQ zi_|)>6^q5|xWVj8al8MWX{BW)U{OgKwva00Fzou{OfA&3!O%;SKdZfvczShCXk2Le zy#=WSsZ}N!?ELqW5Lax6&JOvow>P9GgyL{ZS>PDLl)(W}B*-fO!4(n~hD>{S(z zcunlk2GoH_{iB9`yM4Puy93>8n+Mlt8=v5ps1DV&{Il8HeXo(*;ecJ>ahDuI2{DGi zL9ifV5LE~}q{^d5z|z;&_q(qJ3Hz(U%Pnid97yODkx+5%R=C4FHn%YS8W%@*6RQD- ze)j2DD)_}G{T0yK3p*P^^`7hOJ1^Kslh!{EQw6(VQM%BKb%j*7D*0-T$9)a>)^pT@ z^@#?2#^(}YC1glsO#viq5WQJNelJk(BWW{g|NgO#i}DQbPWdR`yrOcDXNcp*ArE1z zF|7pFptJZI(VR{8skI_@tyng4-bYi;RkIV|UW#17Lp8ZIpqx(^$>xxu|9*>5oBx;( ze|)LAM2&%Cp={i8Il?Obz}-3= z8#(^*(K^HvO?>s-5Zr$iT@l+;4rVSG+DC3l5fbB`Ox)i!JZi0w{`s095Cf|LR~k_K zjllhV(a$~q@1J3Nzu-)Zz;Sf(xRbaGxx;9oJi)n>Yay1Q7$6q}pmj;Eo38JC!>Xcl zho2{EL$*e0fCVaH{r63ozyd{4*M8A|3OB7`y$-&RiN~hv z|IGya?=}1Xs?`Iqa=^}K(``YhxMaT=G{u$Huu+FrXv6d0Wdi7P4g)Qg0W* zH-&S7bJ!|eEyDk~h$r-q>>TPG>Y`r9`Q}sw?~XH%+=gI{)&Nt92rT*i`*MAKV2B)`hTMd_%B>i&6kv< z?{;Izh>Ns-rJqfMa>S%q+)+lgCW(=fq2E&cmv`|Xi&iwq?o;z+^G1sbTrsmY6DPUu z!gPX)ZUkgGoS0Bsg_#s5`5C7cU~7<_n!jLGx}4V&xUH%a)fr0gje5Q1y8LQ_bR@wN zS+=2+)Po!I@deI-w#ZTqDVg&NYWyVoaX@x`!bC;JXEKC?l4-%ynJgWe zQZsrvYF06N)TBI}xIQGaonc2g2!GGNZB<3tu9!920aqw9aLjxIqP+>xK86?`S)3Za z@TB4=k3`k-f+U_oE9M0-!-+LZtG6PA2U2Z?>@F{Y*FLX(>s#OgoCu?8*_sT3w#rcZ zwDF-bk+~_)=%D?}`Wf;UbjG)MekiP(9kfF@L!VT{o6Qc4zp>uE6H2Dt9m9rbQ|L!> zIHbjg{zqrmw1u4ay3@lIyCAk

    ~I00bcl+d3c?C9#<6mDr_5GpLX&;XHSby$5d!M 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

    cUb56|R^TF2>+qC2a}L$AdUXQ($z zIaVx=B3B@^yDrt&ntS*2GAK`zoyYLwmj5y5F8bYCvQS|cYo+eZz#2rS0iQ28v>l@zVOsGUhJKWBELjmBW4ECLgBc6g|Dzf zLi`ReUmF_!P@dSwR(um!*8U5{;u{=`%rC5Rcdz zE$bCNOCz2?%YSA4VrHs5*E(?tT0LIpH<8>wi~if@XB=vcqC6A}AQO**R`khidDu|B7k=za{M6+U3wNa)9}0KnKwU z5#o0`?Pad@Knm#~q$Rt634#vHdAUz26xpntNC_y^EMghG~p9)7qJAs|OYrx|>P^w$uSwCPTVH?1UBrrR z`+WFy`lyZYYP7lI)gfM}{iG8iz#G~*Kcl;}?~7c6txMtp$5RxihxPN)+NKypI^B$E zt{qTQ)-f+$aV1yWglo>!H4ps7yN4_3rN2x=s%q0HK{%)Fg8XDIlN&6;{fCWR^ubB| z^&AbUov$QXA08v>z!4E(`g7jLeTn31R-81Ncc0GQ(H&7xWP;bKG~+d$!TU#hnWc%m zXw$f~esX_Ga!Ldi@ydDRV^JCL(B_r6)p0Wf{)hs^qGHc2Q=|lOeq)N|#+XJMQBB}N zM%*joeA4W-wjb<=&9&2EhGf9?B}{9^QQMi_p~qk}ADyUX*ov-CMU3jP0UF-TbZgm% zDc_T1fB4yPk@Nb56Not=iqp(eN~mZIoiZ$D)ORE-8nDUrV#P=?U6Ft{Ci*(jnuIj` z#Rm8{?Ei(nd7&e+;P%SA6a3$%BgubfLLoozJ1=5ZB@3wSB3yVUq8s{_wU#9F`{^G|X)nV%=j%eGe_D;?%$HYuN# zM)dy&4Q6*snEf}I6sfV(Rp_L71AV`?|HC5`1+d0ly&Mz!GXEo8vU)dLlA1I;qm5as zN&F$XvqkK0lDc+`3*_B!cR^_$rS^BK!~eU~jKB7LK!#a;;iA4$YgPUm1pFKJ?~vI@==vqI6=XPUrs1^l+R6P`;aIXT)>jl-B!`^|I$njs!~6xy>~|bxbA^)d z4b@^z|AztoC;GpWEVLivy~#t6ITG_gsnrpqHxEUqU-RMmDH_B+P?J0!4!)X#4hL>D z?^##7)FnA5yZ%j76~Z#ja22!iiG-#;6$;C;1sBTx1p)tt{U>PeCOU}gQC=3}ar1QK z5Tyt;oZ8RIc2VzKpqR$DC1uK8Z?cPUQR|$bNW(v^4$S*l7&NrK@3^XSaCf41K;>$y z{;B(@;IS51s#>o|{?7S(10W9_z6!THKq9Po!QmG^J2W;qTL-$E9wi5J6o!hK)+46Wh_w0jxvJ3afCthAMP@Hp5i zXRKYkx5DDB;I^SYY7ai~y-5@8ZWr(SN~Mo#CKFPS=#LOBnt>^@B1+7vj<6fEA=Uj2NCPZc0CH<1%#X? z)Ju>gtQRHvm1VrFvPCTIB=I0s)@3a1W=jk(XC|LnbzA&}sPZ-~kZK@hNnuf{OIiQg zU$?nbO3hM>1iF8+@^#;rP#x(e zOJx3I1JIcram{I#baj1cl68XOk_sGZnH^_bJ(@6vC7UdMn7D7UXDx9zT_RTBIbHj_ zB2UTE^6nh%uj1k2gC*%}|?2MYy?64rFPOT^2@qqtfL6zvZMps7I2= zYRwiWBH3lJbDfHepd)s+ z{M(f&3q1`K+rcSxcBQ>fxKA_oWvxx$5Aa8px_38qF_7;$XGhvRF|X`xB7Hi}3@8b} z4YNaCa0F-?^fnc(&jvu#7_?>X=^`Pp|Nm+VdUGfef;DLE{%@u=2QC3sgVv_tzf7|D zlE&Va97jT9!{ks7V8!TYU+}N&-=L!%kOr-N0gr6h(`Nf80{@23gI+Aih1N*5%uh9+Q8E@IhhIuxj9_Zp|ByKtVtYZ$t4fLVfY1i8u-a`aN(witm!c zo5Zh-%Z z{+STz3xpyv<9DjO{y!U0C3{`I(vHhWYd!kFir1t$1PPukMh5c?IB{Cj@&iwKM9g4q zV_`=YMN66~rL1`^Mbn<5>K|Xuhr(H)fEDB|2Uh}gL+gpm-{30JS$T3Ra>;cvZ&`em z#ZLsv!iLdz^nQ-_1319oI`V+*?rGA}-vAnUKpYJcth5%r!su&$KgV(Le1Qc`Q-C>L)yP$%59xX3qkDfxC&zJef+5tei zAACW&e$)0i8UHG6u0qlFd^rX;&#+EHI(T#)yXl5CxLZ|+a^KHjRRM}Ktuy$Ml`XcBMX z5v!gTt-M1-rb*0rUPBcXQ_d#Rn>(LFv`JtuE?+rw@m<$XTsqm}9|hPsKVylqCsA^Q zKe2r;c=Iz%#>`iaGL|Ug899+C(TW!c{EYjgn5hsXM>)1z(bJwe>wf~U{$%TG6U24% zrM=e!chI}C^RvGui(N{O2>V@)k1?^ndm4{GyaHOGXCmfQVuD6?>%4d~zL-9)E zZu5Ge#C$?E0ftXPc1QQ85q`w$>FC;A4+LsUrvNHe7t^b%bqrnoOY6iRmvp?lgy2ql zm-mph@Um0=I_|AS-BzFu^R}C}*|tTkQHB9D8Fa!N&WkheQK-hmBsnPxTwtazZ^fv4 z*p=067BlP;&r|QM!e=Z|r@vD7*kem~Tci%Z3{qYybI;ll^6@%jSzBfY2R;v?Pxhuag{&@jlv?0d{N02_sd%&nLB* z97PJa3$NU0cz&*aTm5t8R#2We?u9)-Q;~u_Fr^JJ)$|nbN*&soAz#iEJ-QX}NnP5S zG2}jc>cY>P-uYpEYLJ*Pzj24HR*uIV)kUYZ?*y81K6rJ$mwA%hNTX}1iD72@yT@3! z7PE$)UfHKozK05dRYaq?=XOBZ=cCGU-I20}c z;xU?sd^gox*z3apk3!)HqUkLE%Y5C6h+vSyLDm`>_H|@^KquFS>Gv>06@YMB-TyLP zx5-e&6KkKLW17n>RnV=gT#LC_8D08k{W=Sw4bwF+1mkW1j4dcdl20UD-q-e(-tcIl zU=4T+R#>K4C#WZV=C5Vt!5h#cXgmQ>odT?T8a1!~%s3x84rO4$##rW}!#80NEW{*^ z9ktHK&rIyTy8IC<-%Li6)f|sPhf`(S(r2=2yD?o49U*VnyFK@b4%%a03)TRV@s{!r z8d=gG+s9qTM+!b0XQq?xy5WX*Gk;~&_@vGhUqUc29dcO0(F4UVjYvPJk+%WNF8ppx zOY_#zd5@oe#s~Wc`iLi#C9b;a}aB_BU7P-o|>GIv~Qc13iR{1)YkIz1Eu6 z27a5NloZS*5@Qxb3({^#;Q@A{@$@kt2MqcuCt1n>oF{*v$JxgG3$G(_bI9g05V3vK z1tKeJg*9*AlRdRwwtc3)6yyn2T-}FI5d%1(U_L|++#yeUO#$A)o^r3)Yx*>`&&in>?Nc!G4oe>P7Nte1uOpU6 z0`DEN{5`X;E~yTJA-{5a_oP7R{VhgsLu|?fUi@?)n9Eg}0E>8^3M}>N+%f33vGbv^ zfJ}OV7dz6&vEXDMXyhVU-KMmS-Hv$vm8Q>o{6bUt^z%k0Q&;Y#F4AI7*i%B~Pn?c< zr}mFKO^<-a=kx!PiRn`GXkmN8^V$EmR?j|{*34<+5&mNE0>nwVUTc$SqJVMyZ-E%U zt3)sbf?gL_A0dObJDP#G9{zU98{0&J)Le0mEOFq$L(kaLNsk}UqTZ1|9ZRcyyA98A#GDl66&bQ>ww%i>unI|8MZjEZ9W3WJukTdsH$c|VV2KQ1T=#2h?D z9XzSeJ(pQFmhQYP8Q%zhNJRuaTl$cH?& zowau^dwH8rYN5VIm41(J)mD-ruM8YdPH|6d{aLa|ehy4%L5FkUkjSAC@#I#PnQ0hA zn{s5PclYJJ7#NnVxr{k0Kfk&6i)ZNrlXBmH;+b8X21%s3`^G$3L#>DvMsLYW*BTM6 z!zktC1EE7Zvlvn@Q&nYF&Q?yif4nvOpNzK?LiMb&={q#i_Nsi@GV(Xc(x`8PEC`$cC z3#Eji{G&qms^hnS`nK;PBa8%34_v)6}(`dl}|zE`06oFH0_+ zWXxINxu!;~&@r$0D0V8f zvQa+dXfl(#W=D$qx$;73Ebn5RnnPBxRqR+;t-W#8@OVy@gRLoR0Q){8*fC*=tJi8N zQ@n0xoUqZspD{HfM7|`&Y*V4Av|Jr|XH9`FPfgL2AdkK1fgKMDjTAnMwd|ql)N)sslHzhsKUl#vf%e#r>WG6>d3z7bcP0x>LG?1l(Jxpn zBU33q-}n}yFh#PlPw63f&Q_v!=5e^Wua;K2xvPdJD~pJyMZei4hbObzBS)wmwMl1i zi>lh}O(1UQDg?wU|Mk;%cJk~QHLjAlA!O5?Ci{0l% zhUWrAIi|6>BWiQ%QB8CPM*_@wT{jx_lHK7!I$0vf&o8yfVv@mGbwLNeL^z``0xiB7 z2xgj%A)is0zfldDA}w#kFEX!agjbr;Q$#M_`Gp5ysEqx>!%!J|S;VQs2Cu}b!^WT_ z%R7MiBd<}uFV(40emK?cXi~akkFaKHNqDJbYDsOWWW%cDXnN1;qqBKV7Yc*$V$F|` zH_nU=_QR?6M=4odf#8J2ri~*`=aB~YBCzsE0H?9<(%q)lNoBsa)3&Vh!T3PhsIBu( z{nR>Q|%wYt-zj)oa#VwWf?QgfxU) z6mVVG`8)0c%dF;7uCyjwJKH+u9bkwvb*oKRI=#NoIS0)9W$!si(6a$wH=YPzFYo%^ zFF9m-A9-XNUC$Av?=NQJ!yUe~-ZJX}ztcx-mWl+&)$s5D`t!0*{bPKv7>pIwhxaEpktpY^hi<8*wgk5078D4#tJX=^7qs`cTQR@Iey6elf zjl<^4V*MED8)9OaRdtKraWK5=949;zDr4XD>R-+O*Pv4966v^gbPQuZvap>tKptmB=V_rbY zS)p<0?!^h})>Zl#t8r*=;$F|*yqMJ3YN)&q;+|M# znF4wE6)$Lb!m?0P;<9XWti83?N#^63T_Rhv7}XOsDK&zI^curcgUa`_YcAI25MKJO zaI$6f$vo7%xXqe`_TZl0DGk*0R`ofqxUAIUW+`LOGpcwzD%4l?G6ydj z7%z3S0`@#*wsPK4rUy4o*FAp)pzGnJ_k9)TW~d(DOF#Y{-%4|L{OcsLK4WOPd5wi{ zAz_JX7psv+VG~N{yP23{7xG)cQs)kWcZU_liPwgd##=P$9@M;R*}Pd+0JDtglNnDw z;};<(qWH*6ASWX}sXU%SQJ>#iq{hLHnUqxA2I!IIP722=MI%(m zMV877A?9ZwKtW5coQ6##Y|9u)_Qi#xUYOAM9~&1w5E0R$+M6<3a(EIdoJ^p`3AjAWiu(9zVN%0Q?ZoO z!N>PMzr1qeeIc>&fh@wrk?E1iHto*Hr+d`EP4D2&WOjO;2vCv9a!WZ$aWB2S860Of zvTTLCeZUu~>TRM)6_MIM8Wc8a^OCimUJjWdn&#_&K zKiHktl`4T02L; ziRidTsDUVItyeQb;*2=u?47*DajpB{x1QkAMWKy6@t z+I0pcGd9zpGX9EmlHXI0Indox@snFz7EGvh#p#XqP%o?jVYPkuhI>kfIl|gXRVGLK zO;LdxQ1`UnG~kvFjr}FYOm4leD1%b>TfeMK!v;FN0IK^fUS?Oc9Q5Mq{;+U&KkIl# z4&?BWkDouq@6D7kLq65__sWHxuWuYb3N_&*28cWRM3Wi3@7*0dn|Jp4O_s^rYw;|{ zU#wQL4Mp#|Y~7N12}@**hP=t4&iQ-yGu#2#Ts=Lx!Fv7}_IwADxMaKx3?S3%8xJ6Z zq~?_HHKqJdlM_lni4oS=lvMIBLkDJcmAw>;_*lq9F0AHjE47%nl17z#etbxTZ6{it)L) z=)}-f@=fBOx}D#nU2Pj6JIlyXY`e1=OX(J7ewNndsl|2G6%v{ah>@F5h1Po_h`?it zjR9;G#d(>Cobz^JZ?FHtiM+fQQ}bJZ<_`x$cKa?|LE@b~BA3fBzSw$k3Hg;sch_Hd z0zW(CO{>uLJdrNrfTJ+8dt-?CcwCNHP^m#-?@)3ztMndg*kz*l-C!DhPZ#!nrt z-Zjm%?=_uiDc21dK^Hmupnz6s#ak(6_JrZDFj)j3d3VfcvNKXu5*vP z*vjch;bCbLUSW*Al{V0*v%OU2tX`5fUFSbuyKwNN&;?%+IdHoz@FSd!eEv&9EUvOb z|7-KFhrV*AXoi1UyFeQ{HR;Gd(w^)|^f>LI7dTiow@F&{-c>dgpC32zhgS%zu~P#F zQ1$YFHp?FOf0_FAX3fY&s+F$v26T^2ilwmo$`{w0-Z#&kE&cG#eW-ZiwXYNndI7$TsPV>POEe&sO-O7Nwqz>T(o8E zRuNJ*vf3sSZ&Uz)jNGg1`9(EFX?&KbCS75#3NN}liAuw1*5{GgH>Y1_%1h02t%+Ot zIT5DZq-DJU95}v=MAO3iH1qN&7lNtWU;jl;-$p*eg|;R4!YlUE%KM)@|5fTIrsc_u zOwa%p;s)s5h5yfuPog)jQ;qxwy5w%wj~HHNmF;g;HjXtqAhpZy&bccULB;oy2I@`-f3`|IPurD-5aW z?u8!sdwFZSY$p4p#n2@QC%EVTTLS+ljsJIT%_mmHC+Wb1Korm}vf-VzEI(yWXI+n1 zw-~Z;^ySDs+g(7ZIlb_|a|8cv^JAuH_XN)YtqppMkb*Rt4ClWu-W~nzl@yT4O{bZN z)epsueO|v|l|XCO9AHVP4$Cv9EPv!FF3)s_@G@1U4%em*r_Bww;=igI95eLr9xNwJ z#e3!cJ8EIxd~sgb+9LG`U}_Zcfuq4(Gc5e!# zojlnTq#73pxNNK@4|)4$rtdC%FiVt~-&S^SjMHQJ-$^NchnSJn+zZYyKUhrqBHbV(72x- z(tQgZ7P9lCq4KY^=mJX9eG<}rX7FuNjOE-fN!%~vRK(l|9E7m4H1UjZje{lV1;7I# z@1S3z-Lm`ml}wKw=mmg*{&!H*=rX=;@6||7!E2VNQ9pfXTr?NS5F1IZ^$M`-#%IaT zJ5xk$BbsC+D#_<%nl4x^PoYH@RT?WX(@$;VoMiSNsO3b>?B#IXSq=;8hTUd$d>l7S zNwRq+G-+Khm0hYf_5Fg4FWXrKhg`)i$)n4Lfq9DlMT?D%WGcskjpzPSY7t3Tek$*R z9N7_Vq&uEOa}D6Qpv8N{^bl8bszUqIeRsVeEoici=qsAVMy<=|@y1_!x{9tWANYw} zla(o){ucOhj2fxx<>l~Q#X>j-3nqFRc4(c(otE6R??1;TuF_{e>5gFOjbMpe1ZCHV zjsJ*cTYsNM6*_{`y>R0B#Ekb;Z8$y^>zMI@UjZLTrwbjy6IU5~p`!Q)-!;ZXeEfZF z`};V@-yisO9y|_4UJ8f4gWoG?jJjUSf<#fNJ~cQ*O(V^kbW@i=DKhpL4*cFR98eOu zshzH!Ydfevm(#?4si14>CdAuyudRWDisSeB_$4Y{W7LnL>qV~Eq@+)hhHk4FqZQ3f zO_2q~K*rtlh3oZD*BSH14WW}y7;mdM8TvkmDHmGxv%FWdX+=+bzNF*LU$f1QLh6&m zrTOfda;(N&kl;F3#+eD2rVOhw^Kxh%e)sHX@Ba^ggMrTfb1ou3hA`U)kXMbn^f(qSYlVT5(m%JfyPg8B^Fi0EuZE@;rUj@ zOjCtf)`gnOb5PQ3o((2O z@0S+-gsnIWgqG=d%Rg!wIYdx@eA^|x!lZ*)w2`DZe10#q^0OIxdl?hyzNL7!QVbeA_@n8 zcO8=){fRLq#u~lZt_Lc9z+A#SM!5F7Z-=iToW3On&?vI83-%j1^hWFA^o{4=zWmdU zz;gQO<(JQIg1=*o5u5tazD56tH2;gl5=;9V_b+Bklm&mRU;m1l_{GSpL!`a?P2{^v zhnFEQF@il}y}v+v`WnkAk0Vb5$`bl9Vh+q0YIKU~i7$vufuit@9aMFYUrhS(MLIyx`<8HRtSUWL@C1)9OQnK9&&V5-i6yNE8y;x z-M3Qaa`f^{yB;+FubWCDlgzn}^c;6lEV?U3QB@$T_KQ;AY-1Mj*?ul*Zb1ODe`@>i z8lfX2@ryt|qkrAvD3m5E#1PjLp#@bRc){wg(OzQ6;feWopkal7(OTvj<|*wBktcdf z3A)&1yDJ;w(94tWT5I4_gc}^6m%_-I-@HK9mco6A=yRR;P(^zEa9Al+@c3MCfsr7f2^Uouml5;;rq?5*mR5U2;ec z-*`F%4Bwnhc3`mKy>0eC9BD%XkRHWuY}iPL5YRi`LFVY!v|nptbNk5|a?ZW@?RV5P zCWjL73E2`O1=?+o{u5E#Pkl`i(j|nfTT#%&^KG$%e9h>TDe2d4Q!JnTtO}&OX-q(s z^$crwE@D&b7u~uDw0mV+_XN8f`0E-^B;kgxL&cCR31i@LBY5wRq)FsZ1?mMu45Icv z&G?|(=Syog99{IsSI7uE-f_1SW~~y*CrbZFxPT{W_=_Bb^RJW$QGUJcn`>xn$l*u| zeg*BkY!rf+83?uPcVtO_WuQEt$`;}}`l$EQou3ym4Q=FwP{;fl85^M5mdcHRfkNGG zx90AM(tx*w^oV?neEl2|0$%ey{mT<4{3U>b{awlMqvuP(R}_d*{&deJmI(!mR$WgGjdo9x8GP^udvtHBC@+YElQ7Xm9jhx{(6mDk8JQc|A>j) zXKqXMh3^8vnT3gA#%5j-b>uoD87#dEoLk2CV7`gRPbrgaCv%iWa$qLCqj_gSFqp6v zOkA@5<>6jdKq2ziYFj7B(!Z?6Z!X>$mAg}G4nyzI_*Q7!H?AoY{DBKxNEiF4q_V48 zt`}j(E;bQzA5+8EaiTKwAg2e|eA}9NY;NkCOrLiWtjp*~@nqn5Z_-p_Y)^M(sy;+g zngktkAgCY;OVN;K9FhNcO^_P>o0H?^lT_tbEb8v{wBcx7?WFEH?pm&!?Rs?B?A6=- z?+=s#^6lm-T|OQ28oB1+KP*h!r9W%F<8Im#Sr|xaph=bg_>QQ%_8m1C@cX#tPb^u` zqdzfq9Faatgpn)9S&1alKJ%bBiisJsG-l|C*FduL!XD{4(v0n2BPAwGBr|L^<8Lzm z!5||HJ0t8l2jpnF%_9nRU_f&~$}6kxH}~ML95))V*sw*-2B_8j+dET!XNUxYw#=eQ zj1`!gysQzJh{)KN5qX$7mMa#X=smXawJ47gQUr(}IHJL^`bHvD5{o8V#0Mdq6X{jv z`9C7#sYQiyNg>k`3qNx(VPyT5STXKXwN!H(2)g$wPhTviwt}}dC5MEovtiWmtjF_$OA4>1{y`~z#qWP9kzAk&~zexHVS(aBKfGqoBkkI9E%z-E^Xq&ReVC1-Q_Mg4x zQ;((&A}i^O7K=29$UTQ22wGg{Mg9a3&`+d1rlgTq7YZ$ zM~3_fXEyBVIbD{$80GJ{A^15!n;+-2C%z}j$>V3xHTc`%ONqTXM8|)rd#XXbH=>o9 zdX?c^oPIgSv^)NV6%`!zwef{6n!V|zH+u#ox`dTD+#I<`Bb&x%Z~vXCc34znr1DIS ze8$`1KO`WNhL^Tuq(J)jwKtB;4Oke+JWBSUgSPMI^o`$Q&<{zirVV)kq|F9gX6TbW?1F-Z3Hvb- z^>*NA1;)RdEw+7Di#~!iX|^x&(OHJX#8|-BKKiM-;5Pt*MZo^L%UUTL#0M)4hARX| z7J^fN?)X3;1`sF^UhJF14eow5PD76gRevkTKGRh-fk=Mzn*Z}|P)59p=;(JeXK7xs z5meSq%|A|vH~R8USjZCo-<<OaS}<*I5se!k0yp2CJ!B$H^AWOHTT*oGdg*kW<)urY*z>~P5wvMpTg0~ zD6|O+i+j5q&WW9v&9Fm7O^05drPtDvI+A>;acw+aB3lQ##yhxpTwa@3EC-A^8tzb} zo8%D1FJ$Mml68Lp9G?etJ*^ClF@d`Gr>gaDwL&1VCM0zUIm!KL+fym+V#|JAG*nS0 z`1BLO3JI$6=)bew5YO!D!^G+H;$nW`%b|7W+eS%KhZb})y(KEto@ll^7N2%?=d<5BE1O0Wfo7J94HN|R+|)ei@HU1nKVLiG|`GGTQ)4?idcDd z?-dwr1806LI+iid@;jE{?WO~bGXXYwTG*mlw$_&Y)9z#foV30l!Z>|`6*&(^vjP*Q z@Z+WfZ+>^x)3xHArH2%deWj8lpIYLGe^*HVff26}Uqd6PI>ZV&MTT^1@cp*+fUUpJ zt6Tg=^`HeOh|u0AAG!%w+H&;u@>-#Ede~%fkkZav#a>e2|kW%T*F{^V1?N zc=F998oDx&E^Tf4TyDQ{EG5#gpp`=Qfjq0$VC(?-0Id-_rsuwdG0xd`EE_S0HN2~B zn3r49VrT)Uq+*3wU8HX%K@&ap%HK)5!`fn@88@$T;pFhVi+`>F5GkF(Qir~NMK|-O z5N?>GUb&E*C7F${ey{g|xeCkt0K25le;V|o8h3Fox^pkue?Qt^Y?#j>3-}zBOReSs z%0q`t@J&7UP_B(c%GEE#U2>_}5Z836*#K9)@f6gI)Tq&T8i+u3&VdVj((_} z+1LgsR9(GEej-i*>|ybnrM~ChP-U;Nrtr;e&tu4?=e>_lH2S40Q`FfGB@}B#rdUC) zc&+UxVe(vPO;NnXD+S*K*!K);(T=vIG8_WT#}ciFSkg>p6e$6|PpKK@8V6hxazuFg z$~K`tC<+XARf;Ls4sDl%1T%3Nr*pmVGW>2@X2A`MM|yun{pV@A01~kowUo@MS@xF{7}A0}@}gD2gT`DgTtC(qF>5 zN7RK9Z*l|VERnWb>wO}T;lt#_Yw8R6v5-=dxi=4@y7NCa)SA|RD!KE5WAxsCDi_wp zp7BRj+wTpX!DA?j7RVBr6t^6+xMSQhB=cJ-$tdAC0uJ_Gb;RIE@ni)lvpWquHi`0- zSc@~5qcg95S!EqhHQM_6g}ncR>P-1;>T7L-=%%m0BQ7L?kFa9ztlfjF*P$f8Nak3z z$z3;)*G4vE37;1pR26zk`6Tcn zz0Aq1LwGCS?2ZBtbl-cSW$+vOcKkJ*wNppN->Kvz-+yfL!PBt-1A{DCV-!@yK*O4j9Ou)Eu zzD4H-v19ha+L=rk?U>H>VRuW5eK@26uC*@;Kt#;*uLSItW7|)6ks+^ zKIH5;lfu7ehE9R7DMKR|1i!Z4K zX$b0LR#KaH)#|c+bH){7L|)u4{WLy*`-ll|n!8IE+IgxX46Mp1fA@G&1U1+j-G2fK zMy$`T%Nf>D`j$mU;@WWs6O47 z`W@vRX}SiDc7L~XV)*;ZpW&}oY!hb3mgvv1X4Wy1X(akkd?FK~%(BR+!_4Z^Si}=( zh_vCAat^Ayg(CfLrzK#~sj7fmz*1?s`fOhrgTeNoW8IgsxYxy+1cMOkbZyq_B4rpv z@YnC6BM#;GA`UM}D;?9gGFu&r-+F+697WyYf}L3@I2v3fXmwq~8t;@r zJo~)^* z-Rk|F$;G=lvG3KjbA20rGvX3L^$0x7JFL_rsDawFz`NNy=>3xS5(=}EL?eK$6M0`K zFcaFK(5Rplv2=Fq$=C_*0nb<;%Dd8O$u0FCW0Vx#SKa4Lcc(+`tFc__8x{`s=k@0f zHof$x4xqRCO>RZAb2i4X>lDy%X-NxNMZ8$nF-lp3nzYYMCzjQ7mg$zO%OFLE| zE8rRC75^3g861aDp6)kq0CHS%W6UtDuoZJm1=1Amg(hk{`2|{=@XU3ddh?r#+X}7B z8%Fp^nF4(H5zD5vZIHE|@IE9-bG1iRR%^9el)YD*@WPng#*B$N!LBTVD~hYWHEO#{ zTZ`1h&N#i4xr(KVMP18Q*EUU!!keGFV}U%C*juXTQWBKnJeisg@TiPmlJ7UGI?h@| zj}s4ChKrhHwC500D`ZV>n&Psvo;q!dd&R3+bKGqagPq3;l82hE$BGNbi$7??XwIGz z1f^n;eDJk@`V@NuG7lN2S%G?Frd3MaJAl?U2^r9Cr&7 zdp0gP6><@+JH%kS?AnPN_oOFJj{)_=`CR%YD6aWwUI6*$sG4w!`Y%zeF)UZzmM$8# zjg;#$%1<)GXEQEg~V;8)3Y4YZ0w`i~khGy(% z&}VoPUgT0=Y}uY?blQd_&ByfE@);N(BMl|H?#NPFo#=1rGes=5+8gX2>i=P~wl!BW z;S6IkA2;X&xW?d&R^=WJZ+E_4e^oku>%msHw6*f3pNDgDBFRdupKFNx>w}{Q@4f`v zwXylJ))2&7$|ciV1SY&D+&8Us{K5EZb51|3@}A9#!Y%WydAI@@K$E3`- zi|~7l#tgSi8sBVzXlL5SSV_M5blD-BWBl{h<5qbQK-TR^e6(d-UTkFl*!9jdPyn$= z*j+??VRVU=-laUuya`>`bwY28P;mkGTEJ?T#YJO+u4KvhKpR>fi**dD|BKs8Qdz7`%FHFA+n2EI+WieVo0;Q6C;Nxa@4TaqRA);{8YN zr$#eBa6>1^%2bBPZG@d#86-E?NqcC7cU6hzJ@-S%_74U3Yjp0$L^yZ_oc%&RTCttp z7%AQ^f!|=LCZL95y3m%+E;NEE>@h&g-cI7GKV=8?3NBxZsP4DWC z1NE>wfMVr-+uWeNlPHstd0O`|3aQ*J_FLOrkTKQOdJ=VVWfI-6akQptO3#F`Rqmw; zyA@Ie7ZojI0y7^%vlRDXLT9U4DS_2O*MhWqsa`4hc5Rf~+a>my=*x8Dbkt68*E4`1 zxp$y;Mud<=Ia(E3oFF@Q2!}y1jsH@<+OSU>8VB8OoqkU!`6k#e!ph?tv9#*<9Y zl9a;LuwxcgA=+bJ0k0O5`{CQEgyS#f%s>9zf(?K5=%ThQ#EkZG{@u{l+LLYZ)Ntz5 zkh9Z&7!&(9n_!ZO=UDw4nx}fcTVQm!|H)4NQOD){Da9YK4Wt=;ZKlcbLgvbXveGog zs6W`K-?cMDtN2U2q)DfLav(}-;j(r8M-Gf6qoBi|rhmW`>xJa;J?;+8^|jUaNgkLl zj&1B3D$15;k7XWccHsWsP;{Pe!p6YdfZ`$1D-Dav$+!Y8H9n*Fn5hBq$oC@%;=7zZscZl6>j;~z3aq%isk20VcgO7ssMD&P} z=p^og+=ql*hY5(yFuYaB5F{MFeY~C9_6OnzS36caM9jaym=sr$<>@2;GGv%E!cMl^ zSl?71;}I@Mx1Dmc=$TaGr5#tN@}etyLA1QfNH*r3xj*FRFn zsr$Z?HzwDlSI@t7G(cGY21|J}Gss;^#8o;wRH^UM31Y^8ZW9AD7t6!P=FUhGwMCYK@@G;d>o%hmaM9=)JK$#jDPoP8wzq=~5gagc^jx?jdoK5WG$w zeZYx6K&*L2TZiJQMWa zqyV41;R`*h6>+!$Cl5GF`}*Ybq<|SH44lw~nnim*Z>K{TGAz~OmymJ?64zQKI7N#D z!Ulc}3b4tN^zY)TX)l*X(oTPXW*VHi%urS}?$JPu(f87p?IlX;B+33a-!) zDhZD)zgZV-K+i`n$-QZAq{Lrhd>Z+oP9>)nC=EMljjU+2fn*=M!dAy>8MY7Xn#c}c z9lPx>Pfr{jHBLRvUEz)1g6A%8;C(*s%-dx@0spZM?t7(!m3sd!N1OJ7Koy(iwLq|M zV8fG5cho=$t=e>BebnvhSk2|s)Wvrucxi^2u?BL9_w;o0=PNPcrG}w7Z1Em$c3Z+y zDG*6-f03%wMa$9Znu@Ua^ocGhtqm2ywYi89^NsQ-(q@Q|+~}-9@=Z%Ffl-F#Q{!U{ zF!R&Lu8y-N@BmN`Y1CGjn%%qiZ+^H79GKe-_U1|Q;L7BeJ{_vtsTp&-LtIdHTr;;0 z5Pk_I#!xpR@})1@tx+@kmdKbH@p4r2;KMBxk;X)f2SjfkiH$OvYNJb@D^ire?Zss3 zrbA*WiFlxcV+pCMmlZ*xnyEJ{(l@C9Q1<4{Tk6B~2Hz0I+H(zrb7FJnX0Xh&Np!0e z9QBvnx3$7g$(rsi23|4JR6>TDAfXB^fk(ILRYEq&M?*V^Lwa>~A{#ZgT;+*RytD)W z_~=YIb9WE6av2XB`svfVAq=kPOL&9q$@y1SB5bk$XQR4NX7X-&_*5;jGXubm&=!ry5aO4pRU}?`9 zXvaor6%%P>sNJv(`YQ$)B-eIf=734|B+kjBryk}_iEoX;zxlik{0h7PBp$psWxdri z%V`YHNBNmA+cAW45hnDDgP^+rjO&N6vARe_1;@jwhkDNL{_Zu*6AqM?<#lj=nylUj zh5E8+xmZv4jZ?x4hu%SODmeIDqKYx{4&@=7A>jI?l6Xk>(DgvQUvY)9d3yP!PsDcf zP|LLN;6#lFtBcmHEeE_sSSu9m3&0QjzTuMtIGq;oEp z0B11C)9;kFoRR2p#RO?uxzI`I0a3$eU^_xX2-N!9upZ5|M!%AH!Z(yQ`E+n%iU@rX zka4TKm|roav6p;j2Po~>HngJsK2EGfy%YeUSWv@YcbdzuDTI_)OHmFb^rY^qmVNtE zH*#|obZ%SMe;jCFZ{^dGf8%&@q?csscKDq0(xJR!?7~+w09e7aN?_X^5>jyGJ;i4f ziqFj(oF465<+wVk1qN*x|`^DF|gPQe5vj zH!#S;=`Ei;xR{e7(w`ceIMF{Ln0%#@Nu=zgXB^?mCD!kfG%YpoEo zdxH#m6#LEtVBWbMMC&55#fx(Rr}Lp0$Fb`=)`}iVzB8BT21n2D@O2(S%v-tR-L2tJ zcu{?z4@&k|5^tY3)ro>T_F%_?5Bq3zCwr>G=#j_6BHY*RI(=LlQ*HXOZ3wI96XNDa zH|x!&1lLV^AUV)JB@6x&d1kj71-amIm++_rTaU+{CL%HVX<09LC+UCTQQ@xG;X zgN#t1sPKYUWj1Q7*xCIA+f2O=*Tdi(S^z2St2y*UiSfpt9I``OW zq$n=O8`I066aY`3^Q_5H35^QI-*{{{dZD0tPtNbsf$vX`AVO1mP>)z>UrohUA*>2smCUq zGeW+RyzzMjQwB3#Y%`p>IqNCh77dN$DoiuEJ$^lq3WynSkWIary_&$f0PF)O{_rO@ zAr>i2Bz~KO#ZP>pn_UZC9V5o_Er^AJ#v;C!<%nY_7WC4-7bb`Iq5TuNj$!9OQ0S)>2l@PDE=*!l2kB>yErV(r}8A; zMp9}7`q9dWs&s%jT`bp%2wWv1_X#LIrx>i@q@&3C9>{aT!3fjsss0fCKnoYx(fG{3 zJy~-f{J?hGDq%fs>r&aDa*Zgorj-p#Fl5SMvO#cC+`VW zqjPXtS3zo8q`gPt#r6wh@4@)o2a!e<`MS7i)jJ)#(#|bHCDZ_|97o z@|y;2-E#T0Ta|=Vv6CyD)ylVuR*O|kzw@i5vxH4y9(<)&tS{8r*5T3?Vvw1B&n2Z^ zm^g*6RkWgh(g)&_1LR^ct@Bf8oM0h$s@%n_(}~qu;4fOXbk zEm(lI`4B@uW#EWOK&Cd`ZdcQ|zFt7ns5y4I-}$Kgsw2U|qdux~;xOkZrz~l?Q+PzW zUZGN2h+b>+Wub^VXaxnWpbb}p zf?BbLt60z_I+dWIm6TUyjGZLwJu_5*nq<_#R~q4=`!BR8}lUO|=UU=Mu*?$k%i04{M#A+&2Sn>K-ncFgqW6P^czw4v^%Dj&zPtGaL#Y3zq9z zgmdb9jkt__i9c>xYx%{I-anFB9CGoSQ>D&%#Y0$`Jbg56R83=7hR%Te5T6(6K+~e= zBK=?;pAR~HHuAMVH+?I#WGcBF`dh`KS#ODYdiofsIz~H~S-W?#{!t*9XMaI9s#fo9 zrJvF?X|rWk*xbUzDzkjVb*)|K-7=$Z=jyr7@kjwp2y_aFMO=@ZgNh3vE)e|#t&`D} z%xU0aC4NQCI@=@N0|M$G-NIC6^%iTPIv{Xp;L(K~EFUiy(RyEdUzgCYNIK+#mPxlG z)Kwr7EfQ0tD|josu>9+o>*|ypxhvWdl9kjICa%f*_SA~jQ$kSKRQ-yvLx}bP0Z81s zv3_Q;RJx^XMZIo$as5b9K#;s@YDDq_E}*>qng>^{nc6ou*-l*h%feihWV56|vsA9w z)>{EaXUi?eX0xr}zSr)HeM-?ehwjlP?|SEtsOi4Q|8D*wAChML^zQt=kMgMVU4giK zeY5yT_+@QWur5yHm@tF0-4^nFl4Y|c-Tlp8pTO*alHuh3*jIAF?_ zVVczHcCPwrL1fddt*2OuSFta;fmtP&i0cq)aB#k%v7yoA-KDd^tXJcy102p`;-YlF zUWRWJ@)q0R^>#Te?{=e|W!dN6NT!WPunU{{Nb}6x)Si(n=k&;LUNoWg5QVQ!%5k?^ z>XzRZpP6kAHa)S?)B4+|NF~WO(aF~33pdTv*7O&9Ph3{*n=CI`tCx)nnLUQyGByFECbsY8A1)eD zl$9F~Q)v%Ur}t8G9A~I+4g!vEKa}%Ef|I#wLiTd~$D}O2QBw5I8gj=Dn}g?h&ZeW> zDjORvRQ77z_Gg=7jAW#UX$uA?rFMoWV&+Y2X!Qrca zEC4R7S(Ql_l1>+rNMH6FdBmIfWvj}~QF5Mg&hPRebsU;L^*2X*FoCQ#(cXHcUJsSt z`s~dohdruGu)y7;(H@X}zgYM;&0}yRo2fTdD4v$sr{ffB-4u$wFBT9M5SR+fW@l;$ z8z~JV;ooknC_S@;%P1|3Gz_VLM#i<$7H({2OLSiCiG*K>b%<5S0x$6eUNW5Xl%M3R zHc&{nnSm+c2{6UG;RE$ULWQdDO;{B&K^dh$1G!S>H;y9y^A1#rtUF2(|4hr z50k}hDnRey0XvMiM156b)q)?^aOa(Ge8LwpfO3FRn5L}24!O&^qv9+qn4T=HxQo7f zT@oXJ$2pLW#yDECtHlaaILOpwzA6ymi~uRYDVNS-?uce|Af@`|@a@O|fk!>KK#594 z(X6HvToX<_dej6W9|d+P4@B77vR2w3@L+h{itvIv1>IXh4NZsgZGP^bCAwyB4qZTj z%>JZF(Hf`H>cb_T1e4AkNF|$J?M-RyH)u;c^glcy>93IPUaf$)f&pVF5?7#kYUq037Vu!yA~nD4O#-0K^PBKG;)N#G0zn;j4P0=1lSTPcln zlUZVqS{2>lMhz9M#7mM^_|+j)U7lGVnJb6UZdEWoUhMa`mPa`A)1gf#&bk*HRSr zwO18qv%gY#h4XwkSHoRa*L3D^9#tMybiEj#NFv>V3;VQtS^y7rAhhm+&Q_p)=HqK5qrw4c3|(A>(Hro|JkC(UdkQIT;?h6TW+7%Bh&t(NuSsUeqEh-82)2D4bYa zLlN)ZGVY1p;V>A11fUQEOu>uzqGQh{KLh`%t3XonLrnc>ubhpIq~w$Q(=?T0@JRo1 zwl;s=`L^?I8j`Ol(!&p~HM$QsA!hGIs+gXm%-Tn8!vDSsYG=?TIyi^fzf=l<$98p6Pu6vHGyPAG2&nADZDltLN{**=#rRz9gusZLeO zidTectAaEx&AUT|3BZ~_b+&`JfqL+o)Sf zCjgTGhhpcgpdcO&1^y2dr1j6AJr)0}tdf@UJfy%`5i8AiHrkon1ZL%>As;GY*Ek*~L5aw)I16pRREW@o3tH%!Z6CBW*Cy>l2go z0~Qt1TWMaM6wYNpV9@PTe1pA1IN9~F^fo0al8dtogAA-YWXgTI&7+vfY@UM!4Ez{* z?ec3C*Ckn8kYm8Kt~{}-o3mT@F_hGrnwV7H9t z2xHeP-CeUP+>4X26B9T?)vF82V9K?Wl5T4lPoqzlbV)w zUVWQ=pq_0V;MpWQTHmOpTpjXZzUvXwfOcautE;y&ILam@DhQAAnp*f+!ADoZM{up2 zi88+02P1AfM>!!%T1z-S4)_oGb>Liyeo!LspBBacs7&jBe7n8_=U(5ceLyM+qq`pl zEnb@43QB4T+r@3GVCz@B5F+LJ`VNM`R8}-Q<)2GavD*&Ct`>ZKE0z+(^%U6j{@l+z z#vGUT9&H$JOe+Oz?1IeEi%@r^U;6F21v>!9Uy#knu#EZ*8W<11Jy)~E(exp`+)c@> z=}563*5PH)dU$Po<{i?l6Wks2t=mLahN&D9_NVUGsdvbq6O;gvPfRS6fv$1fQ(+T< zAf*LG18LF&@!UtRcQD#*Ewk68g{6x6=G5MvdJ|rXUSeMUxA8~6T!@^!sGS-$yfnN3 zB7ByRr7SX~$X|~FiVgm_;iUs7@!0L#lnj)jW+_U+xGOIPw6@!nZgb8h3WvOElm?=8 zZYj5McQ~MZIS*=$evPt%=k%E$c-RvgB`^n=w^ht@E~yLDbJW-pNhB%Ciq+T?r6lF0 zMV)O*YSju=I}yJGKjM9PqR)PEFVnICKI?(L1eo{z zmGFbI&p2apM^kh0r3Ma_2F@(u`m1*f-nG|jcM}9(`mhCMeGTz%zX$bWhrgp6dxc$@ zmi+0dM2p!8Aa`m@ZV)MeB3~1=!@aenu1S|ab0_V!ZI}Dd#-Aq_(`Od(Y;)E{1C+#H zeGPHUxP(5Hzs1%#rP$nhd3kWM{*spuL5L3l&+9KCuW$UYQV?M&AP=WzhB2jyP3vpjP<)Uj3c7P&Al18q63C`NP+zuOM4NmrwcWa7B8moKC-jMxXLi z_=>b^IURomHNOK=bSL~AwIK};h@QobuKyoIeFab)!PagP5(pk3xCM6z?vS9t3GM`U zmqivPfdIjS`;vuV!QI_;ad%yGahJ!vx9a`XH9eq8NIjrX2D&4Dk;@Z*AnT} zsT-TX-8Fy>{79(XSTz2gJS;UNNWG2w#JdvCav%JJy#K7>SHf`DfS~CXZn-PE_$w`T zTo!C`#72jA z_0k=?07G=d{CLFJ7zs44FP*S}q^H!Lqde$sb zJmYj4ZudOn*CGgR_a4(%#hm|*lYd{BD^

    qWjOV|0wv+O_c6gG2?#}1AB&{rp*6s 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

    >N2hZ`NLyZD@c=6+ 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�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�goTgNxgXM)gqKrv) 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 Z4&WtBh!KW5A|L{eM8Xgl0cF+X{vSjGbPWIi diff --git a/docs/LIBXAAC-Enc-GSG.pdf b/docs/LIBXAAC-Enc-GSG.pdf index 930b75e08c2720b73d2dfdd0499cabc77d7916bd..008595ba28b6f66c8ca3823e6c7add0975a80d72 100644 GIT binary patch delta 251359 zcmZs?WmH{D%rJ~wad!^xa1QS7?pi4B?tXChgVW;D;!=vcyF0~Q3I&SG*L&~#u4g^( z`hI2a*~uiCy(Y1@zkDFb}WJpbSTIQjksT)_VT=YN3vKky$47jGi~+65X6)VFY|(?Yt#%RPh1aj6KEo z>Ps0CHaP2xTqzG`etf0Z`<^;gkp3Nvzn$F-Y;mTADR;#Llvt8l--PlLPPppSUYa~b z;I_~ErZiMg2=Dflvbdi~@w0Q)x%UMun0}J5bS#o$}gtkb0 zY-nGrl|KgGhT1}7zn5!0{6_g~$*zl4Rw)0{?S4z$Von}z{xn!6Jme5wkC0JRC4WiC zriCB7`P2Hsj(^PUi^wErx=O=Fc^tQez$@)|#D>r-Bu_=h|27Xv0q+4#8g(JBHfbwc zms~l8WGFEh3P znp2Rog*k9ym7CQSB+#g+8p({MVOkl-jHW zzXXS|y8}Dnc8bKM8A`W2&V4#wy{Yf32MFU1SX<@bF1mZ|>p@7iNM}k#r0lJJFn*=mHB6?!?f?MU@ zE?i}^@*M0_loIH;h7pKJk$;Ku>g6?q4FlpBL0V8)6a(JGqcTck7a!wdmuYrRNEWa zFC@oV%HNTnPPs*36nuh!GRM9vVodv^zADXJC%C6Tq8T@+twLpB;S;C5AhxvnkLonn z@7x$`H^_8#@bDA3Hs`fbmGK(Ognl0H;qrDoWt9!r{xB>FhS=TWa5{L693^76#awbu zjDt2TLfZcIU%#R@4KXqGA3C0WQy@126Lpn**A@lLermYd_EJta3s5&eO^m8k1DQG| z^*FkH)i3o^DWBEz(kn(7m|R9q4a4J-%M&B^;$dL^M!(_74fE?bO2JkR>C*|H4Rfjs zVgFC;qsUrUFRP{>3-Ot?1*1C-N*}&N>9Oj&W>pGG$sWs>NfJ}YY1Pn~L{ljWD^i6Y zhAVcUVz6)1O;Ah&v!ad;lkLllP#wZf*$3k!4Od9l4SLfV`J1Fo_O){Xoh26d^zg#K zqWSmSM;C$Knln3OLDhHY5y}1i%n%W1Jcuh|G7KMoBP`M{Xc&HA;|+4+UkGXp`*1=4 z%?EL$27%W>KTRajZ z?%8|s^D&M!w7hb(_;iq9Of{UaOpocOU`$bTW$^u}VHo=zz-K}4EOYMPO>m9*u0g3k zLiG@@IeNGkba|=Ea(S=9_SD%c*sI|MI=P3N2?r|yDXGa7%FOcQCfS@q4sV65=KZ&a z%Wl)ORLfsCOYdhf((d2(Dc(P{Kg?Wq!k2a5`}-H$_bWHVsuY9|!dQG;8C)#&4iGv; z0?rA==RmV}7BDBb!0$UI(si67F{KFkxdvj-!?>N2T)uoKp&^1vb)l?J6idy@U4g&u zk^&B$5C{dG z$-t(|2)WtKq-1ji6JEgZQwNrPa1?~$=GgC3$7JhGCJT|rB|5cI9H;mXw=s^n699A&EZ@^NvBgLH!JP50 zl&h4pI1|cp9*2lAS5v(#NkL+(PQdlBf%eX3N^+XHT+NaB0iQQm-C^d+gGs`>S~c)g zfs>N6Nlg{fi&(g^X}uE`?{lWlYBn=m=V-9Va1)~&wRpu(c$hVi8{1|5_m!h|U)NWt z=Yur|(6DouCu1q=K!Qmu>0r(d5FETiD1TnVQd_O&nyt4HI6r-mE_dC+I7yIGsKJ2G zRCX#q^DQe`YVVO{7%9(y;HBh?#SSA4H z!48Giv~}~%XXG;I{OKc)Lv^hMEI7K#bN#`laIt<$`1_J9Nu+*c+1x6l81s+`dO5bG zJzTyJMdZt;!p+7=9a+9aXxt5Jbw(%ToI8Lnp9}SKT6)WeBP9M>PV6iT?-B6cFA@os zj{LyEQRl97T^McKZi2^lHPU;vJe`wSPn40YVGED-qc1ReEGmYg<&9>W5zpf66SIEVfZ{q$K+ykm7UZ79RJ4v zjSJGnK^Ywgcek7kAhq3)d;?!e&4=9;d4Dtgl*M}Q~M(cQVl+DCSN=&>pm z4{ll<92zEtUD2e$;!x~UBGb(m^<{D#)Vuk7{nF4Y+15~@gr{?3S1jji;q^PY@@7>! zF$1S6wRG03ICsMM;(|H3yh{K{zZc~6d8FMEQsTWk#PEXR%W@&>ICOFLgK)*u5N!!r ztXBs?yKe0dlL2^{;Y!#$t&M+y?)zCf+A>4DT%ES@PO#{RP-Y1ad~2-E5_QeeLX+{? zjzO)oUR5#N#S!LbXBR77Zo+Gx1^bvr@|PMOe|jrJRooWtva*wMb}aha^~~*D<-L#@ zVsxCJs28a3=}$K5XE3dk0X2%fP8&a#?yYD=OfVjLG%~=xSc)pWYCXwVHCBdl0 zlZSuAvS}=!Z|kOc9KOWh|ERHAM?GuXI3IGf*LTv{e${^HNGtqSbwoS6XVB4 z0p!_E98y(}RQ{rJST>BUgNWm?dv#VLweu~=G@Lm~`;7MLn^u=P#(Z3RM2-Nm4yXGE zs=FL(XU=nIuu`!w=1^v|BAz+^@G!4Z<1(uXr>Sbz_m2@T9~GEDQHS3XA~2L=FrjpL zM0Y1nKKLbP*6bj}6f&TY#VA62Qd7TF{ zhRs;jRu^oMJ=D6^%yYlmYg7E2(6^MqWBQV`SAANFzHN z=q(hu^;;!7&!OVa#dRBu^OlNgg`Mv!cQ>@|y!7LhZ<|lhNO|V?Vw;}MSwq%TewP;b zu=3OOfpVAcJ^JUa{1E3otk97ci!3O(@V7J~=-dFIr!zE$q2l>LAFkJ6aRmJ4J*=f= zKrl2toEab{{A2K7XV-oJTkom*7JAirw%yd!aB(GENq+C{^6z7%t@HceHqF|BSbWc1 zu$oa(<(As%_fGVpX_nk8@=9=0aB9e4Jkuq`vyXf8!yXclxcTmT&q>ob*AeY@Rv@Uk z#Kbi){qyGu7$RI$svS2c?6K%`pqow>rZFN%DH87Nt9nQOi0>HW(U(vW&Q@{7()RLb z)Ku!^NVhHiqn4F#g{J`4D92=~zdO|7^xC+ryWYXKs_yUQCOW5a=c$`Df1I7b6Y5SP z=ib_}u0@xFx1F~qMuZqPbOkPcm<&oR=4yPt+jCEiPrn=i#iYz~q~ENN#hDb5&O8DB z8MBh`*M>LuSwKm9C5fsmV^(-hbW975@wCpDyM)fYjLTk+w>lQoRd9|`2cpfBtA3SO zDgi|F=p@f$>UQtRjV!xN2pJAMj>_11=c6pGckwyxcq3`(Lclq6l2N93HPYk*N7F@AQsA?1xp-1((#`X18$;P}Y} z+XNNMKPHi5g!Fh#_YjYYT;SuAI<|@!fk1?Q1Bgp&^SHSDEXR+Y(DoPjKwkfrE-pXV zf=FwFlLPh~Gn}%V>@g&*0tfEb12Up~tC1)s4HMqLs=BzDgxHjyI7(!QxxJ8Isv8R` zxH-4CU0)*nkX6M6QTbLA*Zn|og#*3S)hOfixNr4f!69a2)fH-OQ9gCHICKCrREnH{ zrnHUXET1w$C-`_&pEV+VG|6|9NsFV!S*SM0wPRO*-K_YO3_(M z#ln)fpYN#Yt@@w9)jC;-L~zck4)R;Md48@zSL8B3-;cP~)h}_9-b9hR;_MKhs;@fa z@(0!cP1H|&-x%g%zW;nPvrH8Gvxxr&VS#oR9Pd=My*8Oj5P;jjQiBKmL0!ZYRI0`H zTIHXeGB_gt6%Uoew{kJvU{KEFbEbGwyZ^rJCgX56{+LV(HX9C^Sh&gpfC}qx#c@CS znH@i!P`)bkrN(BU=*Oob(8xt_XiR1*APkZq%Fh)J<#n+i{vf$`Q3dH5tLLDFD z4kcL`k43^0WS?O9#2MuixtmI8b*mQG9IQx5x;uF0eY{+uk$=)vyl1O%C3+De@N zJtY!mSrSObrL*;hunt$&KHl$f25RX=)Lq=$2}=AzgeKaY`+Mg|uXsZ^x`aSfHs^qY%^$ztVMg@D6JR#LoBR$F zo~WG}ECP++7{k{I4b9OgE5Hv8&C?hn_!sa&+J#DB_<10v!j~}oybukMeP|v?o&*&{ zUsMH-AHV~IIE#ZJN@B{8Rv`??S20wGpq$cQly1?FFub6Dyci4*H$)ty1j!LYhcJty zW(tZ!<3L!YkRa1y%n*P?Cj!d99H2J>*wMwyI{hOF$*V8uufH*h-Tp%FiP6`0AlRN^pO9lkZ z4Y`sLBl@3-xdEVmQ-%Lq11e~)e--#BgAUP`|5q6F|DpLuZOE)3*Z)~Ms=t%|vvNF; zS$U#=RtWAN)c>;o4n1Y(bw1n< zk}I%}?6+Ws-;ys-u`utbv}J*GpNa_FlKBG zaWzZQfJWw!xR}rb^!BjQ_W9@bxSegfkXu+KFa`QleWPepSpU}*q^YeWN(=_lCZpw= zeyXh|$9spAGmf_(~+JnG>dww#&bQO(a0@p$|<$6(UnGw zQI1k_w?PkZiky5igucUqon|F`Yyd^7h_a-3SrbZX?@607d3-9P z+^{rTsbYb~-X9t={ngEyyX1LG%ayrILsLYv+WySu;kI{ST-iq?t)o=nFk;>?`yNYmE&*d=Xj#2Ca3gX4k>e;}#m2 zRC9r7aiti{zuR~D9QXxz_>a)%R@Cdf2L(Lh$G%k9Wh5^s-!0P!&rQIyEjd>*&|;yM za4e;EE%PbUPE8noZub83%ditHV#meQ6g7(hgvH3sXM)~e{`A-&Joug=%@lbM#PWew z;zdgN!9Cm_I3V|FNMS1GN}JYPFTI_3#r9?+is3__G}7;Zf~#GZA_?H_zU4D@e7y)( z5C6~jpdNLn#3$1l&5uHcToPlco?i@_r)^Re40{+xT$D|%7J!Y54)dtsVv7VvCjZ5W z--||E8A^&0zVF4RkVat8=ctREr8UQukq}ibg^%e{a3$TCw5ES;SAqr?Hm&Dzrz$eZ zN-w+yc_Qxb+D79y*Q!RQf;8OScCA9GA@@kAi-vNsg4k`k9bJS_3XmV*!Bi#fMhfuY zT7(!%VP#fu>Jlj5l}u)-4wsx3 zmebLghA}qoJ4=78ZeL#DWAGA@>mB|+&(aTtRd!#e4l*`Ep-V@5~VQZ?k}&$3n0UzzS6Ontz&=fC%)rpZMo(qHe9 z(a8D{tBRXHh$&Ju|B{(O z(NI@&$y9l#SBNxVlU0i)#|Tsn4-|SZz1{Jd2^^H9*@0d=&zrISTwqzE)7q)t`+9}@|yMh(pgp;s%0;pc0dP*Z^Ze=H;qh!=vRMhTJA zP{;bu^8R1j3F702&}&da#x)qA`60I&^x&+lHCqTKMq!E3_ofgwrM<070agdGjcF|d z@}d>bz^VF6;d_}2{p_SUQ{<>9^>&u|o#u1=nj&#mZ!$FU%Z6hPvZML$6LGc+;1;ubmt6mTd= zLL4L=9^MO=dHaMiB5>+?qsN;igcTuXhW z4Jy^Rq78i-%hUl>Y-z5&^f84EiFw}@h0w;SW#v--x)y-Mvbp%UQ+AJu58n6npOH|s z^z|Mw_T2DA8Nr{GF0jx^Lg(T~I>BeNX2^2vxZ>T*sMv8>F>T2_Q}l?@LoeEF$&GWy zs@YMjL?wmDba${%Nnfwa|0c-QCh03FJwANYGCE-x{^WF_YxQaIBasI2wlV2_-%gSh zE{zQKiPp>v$klvuD#TTPlt?tr5lK@`9QV^MqJnNv^1B^U665RS2dKgpo=)?n6oX0WnR}@Jb|FAS)8#mS0?|$58%SfA9tC&SqiNDix+`6tmrDOCIXbhYhec!glllmPV88T?n=O0 zSDbk36S#9(P-uDj-Ei)fmuJrI#@*|feUZ{$+S+>vuu|-C}T_uvBW8 zr~B{T_(+`U(Ek;L5UR7{pM)q*>lzMA_i`#g{kC?oI;?!516@jUSgU|W>tCoAn8~iCzMQ`DBc)CNX&vhmxq)Rid4clxKWpl{;dOkF2qL zzW0~UAJ6LPCk&b71a{-Yn0m32OGwn64A4l--Cq7A zJFKjkXuYU>vNgOFquh(iXwy z%ywhq2S%KS*YwjkJel0-9R^0fq0|J43h_mazIpmw1y;;3@`1s`@uZ}A3(A^XZP@`v z%ae`S7Pk2Gwmmm`rJ*e}hp4Iqvsf5gUtW%^_1$N%IWp|BbX>wUuea@9KtduSf24po zuBokAg4fbC;Lwpr7-_ycDTPwkyWJOtN4OMTa0)8>)V_4*qtE7 z8?B-|TUJ(IPe$4&PBe5}cKaF~%%h!lCgX>yVt*{f^krga678+x3Zsb|%baq8)`ZRH zWj6}e*uwR2zXy^f)oaf9QAz|;bUwpSRf=}p{Llr7Lh>*Msnzw<+_T+KqgDYs&InXA z_-~?^GK>b_SDoQh*5!*Pt-@|?RvD& zvAoVeXg?-?`RWhnh)ovVeM9|@e62-H<@CXLwD}FJi)7p^XGWwe1~$eXt4~~&PgcT- zCZ8k$uWwHpTW9k>9&liuDZ@}@DAs7*!Hr{GDONFnq?&}ZL5Y{(h}fgw=<9w^R&v?H z`fcs=d&2i^YlYONYy{cDol9(-b;}y`oR{{|jJAB;Nr@In(P(`GKdLX3`P0Sp{r08{ z{T@jd!=4l39Mm4KM2%5*M0&Ze1mAx&k8c$sqfj!1Z)Ds0NEFBVzPR!0K6VLxw*P*X<4SK zs~AeEK2~v7Z@4U_TK@0sY9w*QRzN|-_MHza!m_?{!u)2SnN`Pue*34UBClhv-d|;! zoRxl(o94q9z)SuY|FGkD9qP$gaN!=~A6%&U5SPF(tm7iG2Y-<;xs1%Vp1CfOT8>9=Jc zLrICvu&ilMiu)|cjf?N+YHy?Q6iOW`oMeg?s%8$fX_cfTfs|8lUI@^cx)$O5JGo`}LpK z=X)tX{6e_5Xm7PacXU6Dk;vVAuT-$E_B(V!=@gEiPtDqgQH+axD&2|S81gt=jCI?= zuJLBZhL`-@u6%SRfNjvW3Gnd{n-8C0{1IOX9aHV1zI{y%3 zU+Id>=FYaXT)d8rWUSsA)YC-~Gn8qa@dk0FsqYm2|8N?BGP$_JUZ~5K3Xs05RU>{q3He7glTxhGy-X0k8aV_i2Fqf$}&B-tq zH@c!0kizZuoud@FADm(m_KcJhB_V`E`bX(7Kf)T^!RweWaqhxH|7l)Yf~2HwoC40v zgOs+)jA!RrVAl^~moS%gs))q|5PZ&Bk)yQcX^07TSEP=) zBS;IH>!}$KMaVE2Om2S0J<4uM9?IX_7m{4}t~;J~bu$J)BYuG%mUlZ&rH`K%%t7vt6dfrv0kS1D$ACjMjF#fmdxr1Pv6es& znLQ=BF!>T~Ql{g0d8cDo!pQht6yX1>vMp(4tpfor2>ds`wj6p=W}54WhIg<3k)rhg zp-0rp7l@XSfUfKD7UxPNT`zCH(Bp z|4?jsLfV$36mW^j78!hp4U&751G#!yW70eXK*ZT!mU^|YICnmdRUjmptI@1-vq{tL z_?Zq$fT>`en~Ibo6>!taHfD-A_Yqw2>fMdje15mGhV-a((d!U6R>L6FdLkX=8uUJT z^n4O_8ZRBfQ#QQXG?c30qOl=AT|CM}R<#vK8}&GAJ1H6!T9f;ACv@nl#pQlrFply0 z+JaqE*sWK-L28_zH2iWY~dWx~-wB?U~q=u{1bc*{|aZ+!=Gbm7sP|5go?i(f8|QEc@wzuP5Uv$v0u zA;}b!39@DrASgF5@O{WgH2|A_qKRb#c5s11OI`bnJlfFwl4SZ&8wEx$jo-*V1;sjK z4UZ)&Yt*UjwzlNNWfCa*51yTvlcXxdfunOY-L^JQYE+wptATo?!ZrWxVV1uwk zjvJ}q7R@5R_B@3eV?{s{JRN!6eRtG3vuj@?&f;P#~NiZ(~R1)U#OLpqeYP# zhy0_v!P1n^F33^@y`Gjcm)XE+w-P?Nhf)=%7PEc#sO&$4nrSrof=bq~xUQ}GSPLVF z@q2|-nsb((&b?yMdIC)spkt&z;BY91!SfrLK{B73=ct-2c(%2KQblng$=?rN2&uzn z1Ox0dvzx{^Hd1Q}Kh#ox+_>2$akarNE5EFUHD1_`l;NmVRXbODAi+pR8NXG{vn9l@ zL!ox(vn-$LJFsHE$Why#FQ?%r(k{x7rDkeZ z@FFDCF+HsIDT9~@vgEpU+ zf`1*>)+Lbt@kV{%mr$l)_A#K}$Hnt|^koQ?x`sDWqLa;Gr+8f9b^(or= zC%?DgS?Hi|!*gJ-=!pQLrMh0}Sbsq;O-!=M711XhtzLAxC$>-X_+Qcf-X3&Ve|6?v z`K^anb3h!A2(CHdt6qrk1P^~qX5owRx8Rs|734qmI9RVi`Z_INf1X18TeZz9@DjeB z#wHpdUybt`918XGOCh*Ybg>*MXJXZK#zgZ2dmR2-j?B*(ySOuai{(nXnMEZf7$Iu0 zXtsy?F&u)r{F{THY)}(sJAhNXO_+f3^tdVb*t>XaW=p$30=-8cpt7~r=r_M8`8F77 zUeURr$)S8t1-Z$;J5Gtov{{~jtg8CsXCk&Hlc|(xV=U_q{oksiO~5lm&aZezU5xxm zP4E@*0)$t3`HaUl2V z-xP^p?*$nS-!SH>UBv!9WiL;_VNT_S?l)nA)FPRpT;;E9KWb!(Jbchc-SgZj{eK65 zTMV0*qxN&1+43mRFa9_-D{Ox1IP-pQ^|`lQHtMi-{`KPmyi>Df+#zgCcD00I)P8!m z6_nf25|I6JcPpQF@X#$YLZhniV93p}>aCjpa>hP-cLE`}%oAySP@z%2c6z;y3Fh&o z!q&#spQlN$YA90LbS#*>cdpz&gzn1Rn5kWRd3rm6+@B;_Pis9r4R%kzK{}q-=jm&= zi{E{o_T#>Rb)|K1MLek#zNcD0$ftL-2jz=^-#D;)Wvs6z^+PY`Y4B4xMi!rM7xATi z0`IDno*U_mc52bz&);*lySqf0AMSUQqHkTI&`#1xY`%0vwEM1UJi~G^KfsRO54Sgt z1+kzIM5JX$(|y~Tc$PS=`nuC700Ddzu#csg_E1&^FM|tfd*30tqMb@?FqON~V7}Yj ztGvQz;KpE(l$NIrUjh0JvP|F54dA2)zTRu45mbBl!tkPR2sq(18iY@C3e~A zaW|R-NtnHs&v(y!X%^^dQqdYTthDxetJ={cXRzM@b0Vw^d1%Ho&Z5wn7(U2t<-57J zoW3#Ow)jYo3r4DkM$Zb=u2OyXpTqNwmdRmqW^)N+C}dREWtNi;tqD@!F}3MnP<8^D z%$Xka<^2$MB5QN3bVlh3oV_pbxnES-KYgNm989{nqmysHXasi&KW};ZETy^I zbyRuijC~`%oc4Hvp7>jNb&D;7>2M~j^!pA6j6t`-KDRYH=H;Jt#67V?bPrXa zFJ{*JAS@E)yH)ZNw(H9*>=zNyJ#g1Y&-`l|aV%}^=yLXDFHHeuIxRJ?k<-!?GM8G^ z8xPsi_P}>RJA^bs(H>C@21RN?T#xr&xtNl~;4+2gWri+Q<8gG_pakA0ypJH7wvbA9 z@XZ}U_s_T3OG;rstIg7(DE3d8g~-}WdP3zKly^umWNXa(2YJ08B|EW{+kV~qlv=F) zDo7Fx2zRVo9x#dXR=ddYJ%po+ze-#Q&e@#1U~;55w}{|jA;BzBx%X-Bw0e!>B#F7Q z;Bjt{`yG~x7EclAr)Zb+4DD$4~*7hY@eBomnX2?=wmMAbWnXmVo;@tm$mP3{<3~`x(3HVLgT(XQ*R8cjwV+ zyTgCR!uf7Kt%oZsd}7)isWLjo<|N3_z~s}H40CX>kBXR>SOyI!Nq{6a)IbI0_<(IJPB)n!Yugtr=)!FtNU8Ev%-_zihdc;0`3%KUOo3L zV?=EYXT7?iAwT>Ue0*^BTo7*N0Ye1a2B|+W@BXbIDa)zSqHIl6OU6O}J*AiFXRTa6M-3qMKL$N<{PF(W4%6>r zX$?iK@A0w7vj|(?C{n4d7 z8of*lozy@tGGShV>16iIwpA&~<8q4x0>@|sQP}nh`i5?nHJ62$V zihrU@2{x!UUtq@nZpTH5+TpyG*V<&M-|*14aC=mrvrPCs?#q!E=jt>tMi`s0K=tbr zbZ|=+)q;A!B!%*EZv8EfN;b(l{BchSnQsN4&fLD;Z3lz1o)BDAm1=08;e3qJHADVW zs`!!y>S|j)u5C%y`}YDxnUR(pD*bNW2gW!{i81&GH_p6%Rc9Acm!be)4jYMj208Ib z&G@f{u{m4|LS(UjVsS0LPOOO>t>S@hsoh&jC4>tYRj}%Abvrh&836n3rR|aoT&nM_ zgAuJ=H)zBgbYH<@HBQ4bxt~Y}x!n()&nFg66s5lX!K|dl1IQfW8^m3CuYKj%7&A z<0Iw=zwL$RlYEA5qg3Ah0`rJuP21iERgf`*R-s0yVek>WU%>z>!7Xq<*`)zs&R_zE zhj$WiG#T6wiAGs*xm;x+e8KJ@usZ}LP>X=4iulmTQ#7O?+S-`e+iee4_V&g;b+{HO>;uUDKdOJMP$7M$~)>EH=%}vZ02?2;($h zhZ>D$ea$oiS#&7dTmVZLePBLfeI!-&#R2)0r<|e3QwGIhrHhC)GQ%-j@aVT}RlpuE zp_P!3v!FU5w$Vs}_olTeMhTmM2$?XaDv{*MZh?)qQ(WWy>c#2Oa%e^NiEjyQWQ92^ z^WQ2!v3Org`BQUOTpjh+0tYrx@3Nk_wNO1{;v{Gg%?jOJB4$-7)J%w~eveUlK1UREW zkCCE;%pkmkA&x_+-_c4u+GTN=U!qksYcLTIkFWgbbW7KVi@)LOOd#3}DNZU}&Gd1^ z^Xh1DXKPRjd{tpa5LraUrdJ+R7|!_MTR7kH$5J7t3iGcwjCW=Hve*m#_8WX1(37ON z4`Gfl{GD;sP{D!s+4%Er!{^wIh@tAerU58>)>##nskWs-YO0`!cy%@-O(wD)h7gP; zYK&Pw_5Dfe9}IcqjNv1p6GNKR5i?obC^Mi{ta`YzIXgClP(rN{t6e(cs5QKA%%-qJ z``v#Io75=DL^$7`)IyUA;zPg=NeuIj2Eop`4IjH@5`HBq_FPSAAHDJogeGqU5%8%8wKlGHq*6OFd7#c9^>4WaGJHC|E|$%^%LkRhSxdUI}h> zvD$IWg^Jp@+iGTx-MjhO`|J|aW!B*xvb}of;6nVdQk@B_%kdD^Uoal5=(1EL$ddzG zBkJk+G6vJd+0y^nqKEgcxPr0Zh>3GgTS`sZK&%eL%>K29T5LF-NNAp(QP@L}(Qa_u zC*^BF2EWtE+g5)cMda0rV?#Ea39r>zcvE$G1mSNX4t)(P;hqs|9}7F8B&CpkAda_> z(`TT{WBz)m`^oarc+5O_VXf(JN6ByVCM6CXm~foGfn`=q1qZWMH2RQ3i2^$~XcTMc zlLqe80lj-F6eAms_*M8HPR0O~;oQli&C zaL~`zcM*N=Bs&6OBEHs>y1A;a+m30=^#;P=I+vv;{$W6b_+o@U55`4JD^4>(+ zz`{8uldW#*6&hlsv)D6JTqwBXfR&z9?VPmzDN<~u{Djl>f{-UuV+u9-sS=X_)I1p6 z&n)4=mcZik^D7miRHM}!Mf@A3`f5tacH_5quN#Vi2N)f9;L__MorJJ@)3Gsk5Y~6IL(XR4CT?;VA!m!8v4>RlM}6LD(+><8i(! z*cEJ8L@-o6E^&sIg?@QqT*?;oo(Ifl#} z1Jt$0`X?JyF9VzD#hZ1MF`Y~_c)UUKgG2>tYzcyGfK+b}xwA8jcIN&OoOtr$Qqw51 z%&XK=Fs$S#U`a0-k$tXjv9)H`(r*Hpr|%lAT2+OP0m%SI<E1ALOcV#r&KYhp|HT z6Wu!JiXT+@AW5kp; z(@+H;=$a?_8Ut|is_)Gs^>JuRsFYYnl^#{8D^KVUR&_VhlGT52cDU?(E1N$jUjJeJC{Rv*S$%o( zGwFxk$ry^G*4MT5_Teyhi{T!D+7~jBMLv8J(q$)xPj_Ezhlgep45qnPeJ@yr&nIl1 zB1giqZFJ)thSHl*1*igy!xb?y=lt+X!7PraVU28QOpP!lABfMReYL;Ye;f<>B~z8l zP$7H#*&;`QrK0JkSZnCRcFWM6QoauqLpLkNYguRW=|Q*kAs3s>RoK@H9%VYtFw00J zb{-0GA}!3{hgt+eEyd$i_{SG#SYXBV z5~)l;&xtjS#w|w-Zj3D3n`!k=-PyvQh0p@;%bJ+GwOG8xbJ;cd!%Lq($JM5|b9T34 z9mMa6LZfc&`)Y$p+`;DRh;q`b@@b|SL*y`)56Evmd>eR0Ptw>9Z7bsfYNqyX1{QT% zz{W3e~YnT;p-_ zmBj9oNip(RCPO7fE~V5?64_fJV=FC`x{a7{j!>V|#^R?bXbDu48c;zuzNJWi!rELm zE~DbH$-{3Lse+5#Utku@VHna6#MwGO;|<@D#e;m@R-h!F?M=R=3z%ue-hrFh*kHr4 zl<|rreGcu8Xh&71I{LQI-q@&@B9=<<@sB$2vm#!Fri=y@Y(>Vb0=m?>v}u`z#!qI6 zMnU8-OQbd)DG=?BATBD%!L@k-NkTaV!ts>=r~h)IWH_L$3r{&LZX3hPK$gbvNFSu? zS#m%R0?i_!!^W=h?_qc$f(yTrY5~d)4DbSOK0fsoa}8UZfhop!C6nOn^GuLkRw{b_uJ{3! zF|u#KJj>0xAK_OXvh4g;S9A9F=yW&Fm?g%Un`sxJF-uYm^>ogtT`Zh4ZOKY_;+thjB@u(LPlEE#90&Z>$|7yLN=)ln zRe02y9V60_((Bmvk_!CQPRe7z#i0ID(EvyNu-;H_cS#km<8}|M<74+YP~cKUhYs&p zWj0Lk2a4z&F1xMw0C@j_hhU|R%#PQ92V+mens@$@ariB&U}vawlwTSYOg)yNsRVAm zbZ$|w@?kdE1*N%vm=_hvZ@h(E5N7A-uJ&WqIv zOivdV@Ye4P|Mn0iNhGz$a>6+JW4Y?VhJ!S$WM~S z)m7pii#-c8m1WL+qV3 z;ocgosr$ZQfLpS^C>lDy(4Eh|Az&me*_>MgAPg5DYQ&l`%Ut%nA>lH(T_m(x-(;sE zq{t(0_S?K1E%@zN5-H^z@)WzD9aOGa^(~q|d~%#cqx%II2RNHKhZNz0gFH*}vZrRX4sW z{F5D)MAGziG;?-P*2>%vf#!wb=g-6wg_ioCQCCrDJ6K*ID05R3IvoCAWQZ6N6*&k9 zdxVL>2Jst9%F=qG423gEv;fWJeW zf4_4Y0oY}nojhc09W4LWs{(h@Kg!C!AN~+G9vJs%cozEItHNjQ~Ky_*O;y?_%^NJnO>r1+j(h7yQX7l z3w=Qk=AM`)&#&p3x@&r7YN~tYQqS8{KH$dh*QX+7#&bIp$>p-_Az1Lilj%4l znG(VWvI>!sQKh!k6Y$P3tvQcbr;pV75(yhuD^6oT#g#T&@Myc21Ltum5@B+S2+=-t zogDzHyueHqmW#e_vG*Bg5{^+9g_CXsij~Ib%Mj3ZF(R#D#VXRB6|XnazRy1>8{hqg zcvrsY$omi%Y@0RqW*RIm1<2KChei;@-`AD&`8wIjeJ=zNv&6Lr0!E#p3!*ccyQ0}> z@H!}_j^4VVQj&6#z#rnj&TH;7xPl-7)kcYPx%5VGlrs<3uoFJg(Ug4N7xoTlW}pbC zy_6#Opu^%22pg*CxMS=oaSlQay*0>O)z!>Px9hs$!Ovjv_%qb_CeC>4^Cq7^ncz14 zau#Iy2JM7|!`Vo9bwBM$y4oU|$6$}95ZM~qS~&_D+R8Axfy)q`GeyCE#ri#`d^w`i z`%9QZR$*(o_J|7oGu?1Aa5=4f(Tw9It=2NvT|?~hH&^J%`FWHo$&@qhZy3)h_+_b~dv%G0^O9T3 zNuKTWGR)r zk6X~R_=|OYN-X^v>ats8i7{`dCux2*3M}o28c#tA(0#j&cQU)tt*)ymkb?sZsdPn2z-&_BVnh%4ih;mE-*9FJw}4RClm8bu=^o8f*WV3;#2~ ze#v_sO>7Y1IQ~=fucb@E@y~CdPm&QN1B#tNZvcvrp(hAx4EfKWm=UA{iVd&%b&h`) z3ju))oG^pskpk%>R57|8EbRfdAMFC{Z{7%#5rgtn8eO|Ct3? zI8*w#@czfZK?cSG$Z*gD#r>Z-fQ1>r_1|+qi_V6_1{aDy@-A?tA14&vsodJn<(ngu9l`CH~-fLz`iKw7vCE=-QgWdZ} z0^evb>(D!WH8$Gzi>|0nKyIw4H9q_Yex=itIZOiXr51gA{kX#T- z5>|eyH`h5i5yQZJX52=A>-CIK8zEkyBBbO-Qo@C$hnN6RFAYO3LYsXo<|?l)Q@+!G z(ou{HUto*GWLIg-|CkYV!PYe>Jbk^5O5~2CDFhL*Op48cnAz*;a@ZLx7(V zEa&JL4y2~GDZdV|=q1XYhaSzN3dmFI%Hyu5NPlr6meD5v`Kx?{G4qsr2}tEc7aio za1}?RW3~19obd_yJlLPa#U-!d(*LnKdBp_~05WErg+%px$)INzm*Zx{Jv_;RQ>DR1 zW1nTr1(pegVCZf-8>hXVg)vf})6SjGGHe@qto=lRlKH@PS*{A{^YU z%Ot87;KIy$-i6C;8>KNFF<2#dU|&eOSTs*W8a_!hP zIkwIs2AU<8DgHAz_HoGxmf#`Ei!MyLc#EBdu2Y=Fc9#aKNX&@mGU~`=A=kwXkfCVt z$zW(8VZx;gD!=0se8^J9cV+K9eGmXw07T2CJ!(ZRETfQT!-U{SNMf!Zx-vbTKn*%@P+E%&yq*Y|fQYFlTLEoCgrkXzt*n z3LvOTe+P`^b)EET=6>rUrSF!)nPzv18AzYjrHF2K0SzvSzPibsS8Hh(N9z!`2U-M$ zS7%3a8eo%izgtINA5%;DB*K$G&+Ot+C{`{I2ZhP{);hx@=b)?czSjF@DnWKyy_8qZ zNKFISM|VY>MK-aT*MnOo|92H}*4&N|QZt&}y29I!Kc2 z&aI!%pyM-P3w{Ikuhm(QM2d?1gWTxW-ZJ)l^_l5coV@MoMU;y%GMButxxKQw1 zOc+1r{xEJSl?ZJ)kz;hT$$iw<;XEZ_=7P*#{biT-Yz=H{lYlx3zwkU5QtPZ!0=KOI zJ($un)WF6<&LnZmtqP=5C}FiPgTdrisf6ZalSf~+JI`Byo!2$krIWm7 zLJsv$M4ak+P;pqF#%3c-*;h@f#BUADiw@%pJ9{*qtREz0mhq=d9KV_Nwk9~*hJMM* ztsAZ-+gs?dO|}kNFsft%JAN_U8-!Qq<_KERF^zy%5j-eGWfCHn-eyD7D`Fed;p$d@ zOlTKEQI3ri7P4)NSE_||M%LzKN#YQ?U{bn$_h;YAux&b&Ygywn=0U*nP!As%!L=9O zK+QI;^~X0<79n@mjo&22np zX`k`|Cpt^h%Udg2I(Hb!?-*LJ!vmjwI_wp>lNlk?-zZgOa2I&H5l)-f&~SrRjF)h1 zTPdcyx)&?{htLh{unjF=WRoDvOxptfMiHB4ke5u>JU*^_>}S)B=sb(-dqiPg=9JX} z{kEN3sJo>pjGf*nkie$PBE;BIxHeZjZK^j^F#)9|!jURKqvY~ReqOmMlfR-s(|;_- zJBULpjWC)&ti5G)$ukYu&>s_X5Dns&mfZ-C%*Pj z>a{TldDv+V+!-{HOcl0N4huvP0^%n}x~h@!kYU5^i8_#@BDI)5q4O3a@WjA{0%5~M za&^NpHzYB*BzYBtY$t~D0r#$IrEKV+@trp)k^tm1gtf0NCy`QoCl_QgmyJ@e9m2je zUr?t;v%S8FW!zUU!7LJ(cLHGW%uVE_jkC@uV?ZueLYqk!0gnY7H!O21qL#4QBU@x- zyF+;bYX@8OvfXt^<#?4*Zgbce? zKu-MnBlNCM8qT4?6b48;E{a>W@s1l|OF@V2(?o&l-u{wV{QGuDN~zl_C7tv~+vqM) zi)Hv~(_4y&ZZXCk(5q+x$s<@`fFaJ}D|ayTZoGc1{GbDS%vpbjGLQ;da$Q=$RJWEQ&n_}pFDXX_$MgG{B1H-FR1>K3~5@7u{Z@7h|gf?}t# zIr;tNDyNmr-ZcwTw4b%*t$#jtN!AdM;vPJ>@|t`ABO|&axk538_0+%neO6Yx$p~q z#?EGc1x7%X?=Xa^;^VNH;jPPFI5=KJfYo7NQl^%i|BM|;0j40bt^;9^3%#EmEDR@+ zCq(f;`?r%1ZGi;X5Ur6wP})|mThn;3f+((dwY#?hwFLD<$;E2*WZ}@yhw0Han#=&1 zM(BgGwY4kF6zmZvD*jRAUq4rY(Ky9QG?X#}gTLr>O;M|U$-En@#K~m>p2C<-ImB#} z!8{lsgFA?aIHCi5CmK73a+pu5rhMh*DQF76w<5SRV$4;C7$lWkZK)ZNR$s!e&Oa|!S9;V3qe^6BE@kCRVjLh zoSu#2CJ}wx!jhkH0s*%>uhmFlC5_N#gw|(FsbRgObP-BeD!Vs&DRb!2*q7fO*^)pu za_W-eoU^}?HwZJ}Q8o1f{tRb|%BVV$QN;hFE$Gr4PVFLONES%9bP>%W(ydM=NGBw2 zT4nVom3a)$OjF32#|?o!G9D64Z(k*FSd@D77xZcaap9tYDY}3YyA@ih$cm)p+nE2^cmCyN5tU-^>u| zNW%CYsFaC`!q{64;#;7Zgw8)Hs1@-b5;k=%45?*VE)4Sk*^)$O+D_q=SJ~In9RZJ1 zyf#O=E)|rhisn!bEVRhY;XbIiG@>o{H_97PfNNqhMsMxfmDUCU!OHDvXp=+ZxU3gF zW&QT}ErP2k;dg!`8+Q-R;XQ)^)4JsE0zr%Fiv2S>S|UP;=S;1J2;Fp4np^Pg@q-tF z%+w@1QfLf_?w=kfokKFBOv{p^D*PEcyI9MgcU4^Bmn|}Kz+DA*MKBA zLkeO{hohq^0`UIZ$@(9D>J+vWC*%zSkGk%7Ezc`du-x1v#lu1tFD_YTo>qWal~6)F zXi^@QOqf5^Dax|W_ALDXIeFiSPy%5pDzMjav!z#q9J%25P1(O(_t->Q!f)e2MAArX z>EPNM_0H-Cz;7AB^(Bw!LzUvQ9Kw<9R|pPm+J3ZkV1f(q9k-&DDoXT9Vtx~uYB{f} z42K$L!}|8@;}7hnQ?d%*Y#vI2X~eUPkPa3C8k?GEuc2_Yx7A;goUV z36+>Xi};(sq=i11e@GR&s7!>(yXxB`W}}zY7>kQ20AIgL9*TxOE#xwoo=e8)yQQKP zL@7-7y#3Un$TH>~frMr8Z%&$1^%Xw!!{7jz3j{wr!oI_Sbz|DkQW?c`N?XT7#08oM z>%LW$7U!g@aN7+eYCiH}X&(1Qv}-igcEm_*cF5-Zieyl|T-M$Qm5Ctl`o)L^ zuVxXBpQ*%fYx%2#f#^8rRKO>HQlgDkrnjQ0g3Ny8DM{_S`|@9wZDd5d7-I zLdKniSq_x%Uya_gis`JDAv#U==f)P{uqIn2V5dtAwd!S4C%V#tNpfqH%-8ksXGvVQ z52qlm{n65L2)+0{hS$Jx*&;p7k#@4I-A2Aq)_Odqs0}d0$@_KM1rBQ(+ZXLxp{GwG zPF4E)sG{kI7fld>Qt+A`&n+N*8un`>t>?7t0;eqde1FlP#9pZWsR?oL`#7V(1^fC4 zFwS1k+|MQvLd`bHUKMtMWOTi7V2!;}1<@o%QAxNReojt+xWy~mzHzg<>GD}DlUQe8 zb@KI9%c*A~0A`z9CM~jTq07uN$MEU2hF6At?6aozrL=p-O*;yvds@c+Zh9%bVEb8i z?0YU4sAV#yH6I9mPRXr9Q$=Upe;DvbLkU8X{iv`%z?GI_uQq>)^|01=+F$34R5g$B ztnINBd0;ugo)XmF;Y*pQw690vZky{?sm}u%^nD=DZ6;(Ft=FR#ZYtI&4fpf|c&wQw zKQv`#o3p;ESQutv01Go(Tu#+Kk@}|>Te5*Z9Q;?AO=HTpi0FGrd2a{C}eoN>tJBg=Z)L^1TLTHv?vcPJC@TFtX5 zZYlBJDzbtbZnEqrnba4r)>+hPKr&S;-k{~N22L7h8$=Mx-f3eZ5mUi|miaFGBZuml z^F>WdERj&PjooCCXQz!beIVHhm0j`3;3!%vm7sTvqRQXW(?K}OmWtwJ40z-w!glvW;6-0;UcNaK zqIi?ecktRLl{~;eJvC1#Yov}pdR|cQs<#4oH39vnrS}Z8!vx!C-*n7kZV<#D`U>el zR|WTE)5VRLZU{t~KL6_X1KJ#c-koQIm=y0E4-3*-xstZ{L`;R3R?qJ?@9h;A4 z`j%9*YL?6qnfiw}IP)ieVAihIY7i+ijE*yM%0s&Hy2kLYin`19@S%XfIIPxM%?2vY z--!)@74l=P#YIW&#%2Q-DQebz3u8P>%MA&e>zbZITuQ5PPX=)~PDkO%?HqW0>fG5i z9^`Jyh!d%O)?`_VC(r7sigw@xes#pN_gW8y5`SCpG94z7#Ft$(fno-6Z+KRBO>b^-(FB+Yv~rDl1su6|&Y`+I(2VVs9D3Sl2Ls-qC!sWYBMBr_~Q=^R+YGl#sdb#aEF3>_Sw_ zG4kLd$>gupNm(y90?JA<)W$+POD?xcl#hdkM1q}dzcsPDhl_Vi&7oI?yOKaij8S1Z z!=MJubC5#)WEp@!HD*qu8tNhs$ag`wgs`VCi5D-BQJ1uU;om>Pae)NBkb;i!g` z3lt(iQk0p9LS_xBUhK4wm?R-au|Hjq^sjau#@$q$_d{Do2BUr@XgKu%y@Col`rc&u z@Es+BI)Lj5+{UOmVIo0&6)_B6`435YW>ifm$GJx6@-$(-0gdkV^c$CI)) znbS5Ihmqe6L9metlysfZb3IV+ZV+e}?8^6khmtw za^-d(256xBps7tXS_C^|Z=yj3OzodZo4?)elmjP6&(@tBOq9(LBFHxIHffF${=M)x zFlN6rn4~jjr<|&~5h9aJ!@>N=#RZ!gUE;$jNA`Ef;>?AUAr)hjZn$yFQ>BGeCbOwi zeIHKObSdQg@{`8P$L-AFR6*9=;Y0!@A{;tGwS$%~ z(R8@?_D~p@^q|}?Z{B{jgR~0iB{YqL^s<{d$jg_2hxA=e&w}=-bMN5C zFJL#1XV(NaB$Qm+S-LW`u3>jf+p6XtaL34k046-UuIPBBg>*fAAp$jH~ zYJH1`Q(1M<)9W;Ah*72cO^T(H9Cpa_A|NL~@2E938<5PapKM*sZcT zosNtpdk(|0&|St;j8h7QSS8rd8_7rMv7M6ns#&?|KAa*_WU%!`p@eL^&N z>x90q&=H_c)0iuZPb&-CCp9$l;R(7gV90bxeNIUyF~-N#t7#Y(x8m|QCwQ%@4VZtd z)KYl*4I!+GyhKOL=960#-~s>nD%Pb{WDxOVr{<@ap_)1bldK?75t|5f6T1m(^Z$VVkcOb#85Me}xC}tiGdlD^DMkO){ukfyFW3CP`u;=<*IEa7D#uo=clKQ_K1Q-{~*E7KQcUJ<2|Coq>DJ1`I z-(3Fz6exl0%v>D*%`f!mpMANZ&_2K1P$2@Bk2czVC#V>ZXvfOL3nR7qn}iF+iKZ{0 zTwRwwdCi|6(}_zdrKM?=SaBEn)3=6@3uL!zD6qOrQ@t*0I6I)efTpa2jn4E1jYDxR1y zf?!H4RM-AX)2AQ0UA~~N`_22>jV_v5|M0_|C4^ORAcR~b^JH)+RZ(O}%&gGeB_FH< zQBlvX#7~)rYR}mMf4v?<;)dmu>dzlQWX8WA?`!y0_s7SxR3+487{yUQMq$dYTn72Z z-TlSU<;e`{d=OS5ksOV_gz7$Qsq@s+->1`1>d)5x7DY|F5pZ3+}-%KF4DcwEJb)Q+x%O#DUARo6&M-OeR);j=`8w$Xp%@1Uuj__ z+mske7++fH>dx58?&mIWI)S>s!Bnk#{qkvJ_A=eEW?140QDXCOYH~3`u>FL*4tfE zgDRM!%|0$Xq-Rj>;RNfKTnh}70yb)p)K70%fUukC!kvIm64YyOkXqZq{kH$+Mf9gI z^5^gIlQR;YfC5K{VD$#>*9SlUN@Qr%L3#&#*lYAClJG1E77BCf)9zqR<;-ijam+Al zf}!2--ULo4$xtXjvafGgO2Lm~l(KzJE`e$>DjgX@XOpCG*n55`sR0p*4G=`v^VF83Jm*j%Ci6ytNvJZENBb$2qI!qqrad$*G6yzd{WChaP0|P_mY)Y8n$|YFjh_kFwc^#J9s#Q?Qm= zaNw-Q=Xh>Tn~uTB|tS51qtcbJ?zghHhiW^BE5$`IUaCT zR)B|5`6LohE`NXYvmwYj#MW(l(e&>LWMatY@6w}e4Gja3|(Nl_`c6{%to6I>ym>GB#tBVC2K zY<-LBrj3Tbzym8|Yy*Z-F0aa>GA|{u&bHOTO}Z^kcf!R; zzCUc}ly83yJcR9znoMiHJ)r(b2Gef;gvXYC68fEus_;9WN?9sdc-f~<`KPNNc6y2K z@2Ytq|5BJ4$=p51k%hr%R#~SLk!O2=SR+863tJMhAW8q%IFl^##Na}Y4tccCHo9^y zVro>9-!``LDON73IOhVo@^^{NJrQedf$#2{7{k&^E;{HW753T5NzoE43*{%_@X4Vj zdd(!F@GSiDh!XJ0dth#Z!I7+ba>4WS1A(|eBy2PXvt}dk`Qp0Tek0@Szi58rXYluo z$Jd%C?y0WhdwGg~bbX2kDI91#Z~*PfzTDQ?6DJP4NSKR4MQ>d#l*&ah({6v#D|Ek4;!rx( zdRSJ???p0)p7;w;cr7lyRLX0RlsdR%VOj3#R_aXLc&9~;wSFi7OKO^y7c(>!v`9HO zs8z_$wD;SeneE<|gJ`I)K=etyUztciP>%t66m-w7S`^wZnvK>jK=8<_iE8LRPHkg? zzeW1S#y_>@as`En2#|U1X$1{A11nIM(5UXDOClTq>4SeS!>i zdyF1%vN0FFB&`RDu~x@?$q5&>0>^3$wj?A|ho0B%A2O3Qej_w|-JJA(&~WCjA@ z;JZxSj&%_7t9cc!>-&SI+S7-r9GAWES-$jv}|#9IEYED`3zx6 zULek>vc|N-=nee!KoqYdYgAEcufwK!jH<3o>POYFC!o#M5EJAFr01w#Po&2H6kU zznHvunyPDb^z~iDKwVkJp;N;+gO`TBO$|KAA65G)y-xC&v);aodMAnG;n1P@b_R}~ z1^qZ5FHB=CIBg(tV=k3XzsGd!;%(jiNtY+$Y*RcqIANcK8ti~G%fng%$EU)2EXSuo zh`q1VAtpgFZ848T@{x$9UvZ!^P$*~HDU)^rDWqfcd;Y2=z-PI3GJFZqpP9a5la=~p z3Als?w|_EdW-AQt8>tc-^eGBx^JMU`33YPCIbuCzj#)$Gpm+V&2@@hh@3O1NkQ{7$ znqXziCsgZs(FcI8#S_kbkMWdas$sJPDzl&@nG|aSu7OAroDpmZO;h>cI4a(9gs?wE zb(r7Ff0==-{&;>%0w)BRK!=7Ai);9<#ER%~b#zgev*)JI{d!@D^^Wqq+8=y#0`ol!$5b zGzT2A?8&wrA--+tW$2An1X_)@Sa(WV%h3^2&!?LOHHl;+9QZetGqJxM1x?BdUC4`YJ>n2COx9%CdN$nJI5oHE-1N$VDd zu^GJAsA3QPYSSkny^L;=6S1S2^%b!riItE1xHth)84u9M(pdHQpYp zE^`W`pNnUkw?kgc<u-?tu(r<-wBR^J;PJfAPHSAUXlC_09OQvh^HYOArojs(B zbDD71kDO?m3BdiI@q<10fXQ-(}RzD2eRP$ zFv7t4-HagS`E)tdKA=(#4E4q|JKpQo^de&fsE0Qbd^x0LyINDo{4sRF4NYkjB(PYN z0~7*;8NSZ|^E#L7j@?v?6!R1ivk8j6}gn!dU z)^{#jSx$UAK~HsI`|ra<@E7~ayPq4ZIaC1Mw0Lsoj;?;{w@kW$Ui#>I9P2=zB}@qO z>imRXyT#V)EG2cGIGPU11l?y!e;Is9z%cD)mhI~jje&Q#$>Zh-DJ6My`7qbgrZzxI z@3UW`&g!QqQaKrHA}w<<#NIIyZCiUWrI+##0IzrP$FOd&;0uFgVl|Jj{hi$$@eea! zecS5FOT?WOh=pudHwzfe^JTv|!^9b8shsGy72;4GSawoA1@`*QeEH~g%tD)@5^1tp zfa!NxxT+76;{;6MdYq8)@qp^rwI?7>EK7Ij3dHw!SqjS)%j+w(Z9bo#4+^GKX;1Re z{eV+r#K~M7obk-C0sw3NS2)|eT=O-odHe?% z+Nqa)dJ?{2YtFr*rm?UP6~Ov;8Qd25^mJk~+HGrAQl3teAF8pY&vS6#IA}nLZq_%9 z$OPU|<*LSZ4Y6f-z*HeRqH;T4&RrEo0QYrWx5f@2oW8hFecRuZiX@Zud5G(7}ybbHa#L{bTUtU^e zNh+6KFu-;e-?L8M+dCMdTFY}JK{cjCM7O#NR1v(8t*VABd2^YU5i_WIsE+c75NGFwf&5&kpcT05e?*)`Ye;C>2lGYe31%qrL zvWit=zD=w9A8P^`viFfO9bgy+5&K~dZtYbM_hXGwAyt1Qe_o^@_#-Q}|DhU=ym^a_ zcf+8mO5C%3DQ_>j;UgMYj0XeC zF3V3UR4pGCsAG+oZUcu2zAlDWGaripW?$@pAyv7FS%(Jf`3aY6S4id!G!4P6`SE0Q zm+lzA^K$)qU*Xvw(G;_YEXaMgQbnLdhrY@P9f3mS{T^?^G(@w)4e=5qJ10y#(l+xzei7$7J(+>$E$$Za+m0m@8Lm{}6FZ!irYKe(}>~p~%v? zfe3e&e*fplmR4r#cn8`{%%kv|7=@xREb327?peNs3N=RbOuj7qQs~`wCc`WtXmPUZ zRldtSFze*Mv`SkFI~Y=`4~ju}^bhhuUh32B8rmtO+cof;RJ1`}`jwfUQanX;!#bJW zOP~%gzz43Opxf6Td&CGjtO)SY2Fv|FQp+PJx#mxCwC9b8P;_w>h&F|WP>;~Q8+iBa za=SrSP*=Bs$esCmlJLo9aUf!7{-hm=qjkv|rAa|B;1PU7?j_^I9$o{I0kXA9)X~vO zz*g_j={@uEsL`7@ES4CrEpVA^$p;T_wWBI4V5nGXFJD~@lPceaM+EA)GhjoucQ?bU z4Q+@a{G>-Nvu# z%i@vDi#*s`(2HD_d&oPI`8UQ8S%G)7Jr&YuNZ+KcWbXb6WQ@C+{O=6%etIZ@Sx>Pf z;8bk}R+8i1QkyZJNP$U;kB!vSdL^5gQoJw1(Oh z_a1uM<=A(`M_sNvE;;lU`v$0pbf)0kFz^(c0S2xs#cLIK)Ux&rn%5n8C`J+8yE+T? zq;IoHaA!_Nc+27M?VU3X#|4*wkO#XpAid0CM=aw(WJv7h%Y{IbTOvTsH(mJ2HDWu; zlMQyS(BgmS!PDJm+V(ht0Tzjfxyy69LY-^iF=99yB!=+~iA*hIlf zzjBV)Xi$_eIM|>eF1LA>SG_*XVBrP-Uc}OoSAnzGFu<3joId(wnZqmnhopW*p?{8l zX^uFUS(yJDB3%9l5w`vhL^wnL1rbK6C}WIOZ!w~6Uh)hZkmy68`{v@T<~!#(FK+h+ zcq7q9p%JUFErIB}U3i5L?r=*+91n}md@V>cIQ?*Ro9O?v_0lwG?D}Huo7Te%?CSlT zec2GaYC9Hm6aa3Yb428PT)yw$41yZGzInK|_&@)BJAawPUUO6|!0-nBtcIPAu2B;- zmv4%=Sfu{^tJ~`PdhoJQp*RC1(a!7X33v^y1c*zpP>C6=W|gvFn?F7(#J${zSP%g_dwAqaByu2xK_={)OgqT-Rq|y!K3G1*v()7kjuvyMdv7tO!)}&5b4u8 z19T58bbnaK3^!4QA%taUQ=1M27t}gk7_Tz==y3mCjSLKI@^OEZO{!T*iXt?1OlDrD z)(#i!agl#l=on)XJF7@%NrCe@$xaF`@ z-qLcC1UhPH$Tl6G2<*kXgu!*to=i#DOaTmPZ%d|}?YgRzllhteXE!}8!~KH&_S97k zi@Ua|kp_cbE!CT$Df)0To1eG0edoLnx!e0@ak7RB*t6z8rLnQK#)N$~v!Iw+l_qYG z@d11&Bx1wXrWK|m!k04(lgK=Zw~7xkha9K88+gqhaHAo{A|=K0*SM9U$Hk~frmDuw?g;)-) zv=)~C`Sz2FX5uc@s{LV$k5qDrjPRR!o%eg@|!Kfg#%zs4sPnZUNXvcpmZz<)K6d@ z{htkQSY!2}jwbWmE@V%@)g`prnEA)O;ra13)pSKasAWzw2ernE^04ec@bYjvn}T<9&DNk4cho?7pt zPn2y2)w*vC{1}pWqO(YjyU|AZu0n6g;*TS_%C7+o^ItsBzf-KWov4smBT zJ`2yN9{XzD!y9c0(tM6+W(L+nqM;b1asNi=e(2z8EsRn1&>rH;)fyS}Ho^wFIvLc2 zz2_+ARya92>$S#u%6_1b&rCzN$*didp~kYCb!i*(^Hn zsMqtFx%KUm_?j@yUoD1`xSWmSFzAh*)o_jloBrp8Dx+x@e|?O$1=EU1`Wp3&s@4$~ zV?~VC(E&2RE-OV)lvph<=9LYomxe)Z%9N_JKY>xC54EBGCSq2ZlVj4VMV3zQd>W7z2^S z!M%rqp>x&Ip}>IrTt`L3r?K*@z-*E?zvEC@!=D#wMh6jd6k7xsiID-@0}UmpYycB1 zo2(>YGo}lA5~7*aWaWx-YVI?!(V-<}b^W)MStU|d*gUbuQ4Q14oW z3!`~WGk;Im;&FsZR>^IYMoc50_4a5);GBHH_L&{fKL=l9i;dTfyfw>yHX0Dt4|E}C zea~X67ZH)#TR>@Ea}5H*3@h>qt;;xKlo0P4S|y}}+@U?T^6z5rg6Ds`1_otTo0P$y zyg@%VStNBX%c&IpP}I>`I%b%vrSEuB!7n;PAesC&71@s z>?4Z;UIn~XG})cgR{bQCN3oV*nkCho(Vn{}O#K;_hp=&{0saPv6##apc@3s-uVPDE zOIq&?6GV9fqiFety8&7EB>!dP6JS?7Woht>6kSHT%L_~FHfCS6Owb0u3tu;-Htj!`>2Z7!qvTgBF|9_twFBe?cJSHH3| zkoeCuwo~~Ov|xXqdJG;HCbOn_Utd^Pd;*&j_#7l+Zb)-x5I)>38`R96BLMuE1QQ;& zy?Fu^;3Qf|iKu51hm6k!T?ueP=`?l;g{)a>s5trSzSjW!E%o$dP(!M&vO8Y;ZLsI^ zFl@>@3B4e(s4lD4z@d&5+28JV4t(eZA)a_y1Lf}-kNdhRj8zSu`Hmqy8z!6bs<-rD zn$TT9DaNm9lp4rv(j=2Yaf!+m%hFIsca}z2YiJVE4*;S9C+zP1C<0wTw}h_ka{Bi% zKoO6@Eq)e|UZskKU2xvQHHk^kSYbh#Lb{0Br$i0n$5T!Qw*&#aXk;xan2h?P1xQrUi;^?M!oM|xJ5(D_ z7_Rr*lB~P%xyN(Mh?~>Pbt3A2fPsEB{vei1bd0+|l=tIDknKvQpc}-Sj$HWQ@cBbN z9C)I)bK0;=7Wk92{j&#IdhmHZ-IBn_Kk5;9)IrG(bYhk83CuDv^|V`+vmzJa8)f(? zCm*2rxgzd4OYb5Z=+3_`u%&}RPweJ&#CeEt6}gW9E;FW&uAJj)MHuqo5U6tH7IjuB z@`y@6a^qRHQYoH8A;OMOvX>>LbpGQMqBK}J0RpH5wH>L`BO%Cd5_j@H@5u=(NVZeI z_odoIV#rrnG*LnvsZ~8}N2nRA9FnX_FXt5W|1G}S9N1aRv9Z(@nsK(ZkOMJ5=W@y1 zmqLdb$%>FOYR`8og(WCvv;xzw9F{92pG?UF3T5AY6~1cXMCtXk9=dMFeP`w!7_Z%{GVAvi!YY3c;YM8wOhqAbT)nM^ z7rJ95V0Y64y8%l?Bd_iRQ&L8$fGUm9VkhxURQI31Yc?<3uKcl7CZV17pChHl>cBc2 zwo;iM`_Pr8kkbL{&r=CDNK)TK(57+#CaLdSJw>U2>S`Q?3>GbGsDelAESnCzO6q{V zSc;8slaU*t6^!Xi(dcZ>q!XzXmc_|%t^veCp+rNmqD5&FFUz79sL%=SrX&i(-?`3} z7UZvGApZsxzeAg|I?9{jvY@h7f&o`4Y>?G^3x_+c5(+6HmnF~j=9+8N2{<(LQ+aD5 z^o)ZjDM_fk`b=QH*85IdAISb?NIhI~4qRaZtWmrFyZ`|G>$h zs5LJm?btLk0XNqA$KI$+pIudK$;~}Z-g`p&N8wr3DJIpP|JGZm{FeL&f&ozCIBrYD z8k@2i0)`kK5)3sTAQ?GaiinW2^Ka{eDqMH>(H#42hy3ZQ1io|Ug_#hr>xR@ z7}!qnj`~is6uS0C6Qgf~dd0wCL*k-!BBiSRk%d7UouGY8JkqkR0Fbw?4@7ii{{y7v zvGbmcNqUeOqs6V_LpToVOO7~u`^T`Q=Uq%SzcLKMy80nwD_c*^IDF+grDy#p$k-y8 zEV?77`Ng!M30et|G#jFY@8#Dbq;MtDbsR$EI%4-U2-@4H2G;>tk9_IV7NB*x;x zn!tqh{@B?~51CBM!T=^;*lr{jhm|r|%mMaSZ42#M8!sWGvOSTL8k~;6I7Mtqr?FvO zA|+HAcJPsGTyHG$%lYPrmoY@(Vy5>BIlcxEmP618Iubou1X#}7 z#&PSN;aMGUyu{1jASOUWoKy%cc@hBgW>e#d-pz47IrQLuN*p%SF5Qlgim?$#aup&% zBE74Jx98{R+grqidc6=ce%GUk;ty0Dy%K%X1e=3v4ZlWZa`Ad>fQOgtaMaOxdOX<& zbpCGMO#k*)+eH8n=kt3xpsmoZPVP5IJaO)$)k0_BN7gulB?9nU1yb7zDK3Tbv15n< zjMzoyv_W>&%SE?fYcjN+x6?NGldW|4gR?OkQ@a&;RI+`o5W|?M59)Vdy zEYg4jk4Sk2Oe)!S{#8hoeDpfEFyiv}xPbSViwl1KJc=d^l_z!@*pO)r0E;F2cqi`3BSA#`4RHpaLi8)UFMWE7`A?8OH z7{iw{LsOjQx|Z}S>eD!Uh?BX~+XNrSLd_3+kc_r5$T&1S)RU}<<`jxV`~v_rkquG! zY8qZ7LtBF+Ke6W=`eFDdaI17&LKG85VZ1qDWlf4l4HrnJT{K~g?O>S~M+f#EN5sGx zDbX@QG&^=v_-s~^F0x{DX1WJ^ycw;?RdHz{F{d+Cg7|o!_Tg>~pEH>y6g)WX&o~F# zq>X6?IGp8dj|$Gkb3T9cusm9cg!~kuZs=(93Gq4*yOrzgxScbiCg|i9Tt;ECyB zQW0)H0PEQ#b6w4m++Fhx6u-LGB9oQVQ5R)crex6a$bwgM)gwhxx~`(oWIPy%Q#`@9cyid=aJSqJH=oz zse&4WW>K7Q0>0)Hgg9GGW9XEJH7ca~#)jB=d>F(s@@zfi;Ka_ZOR(}>oqhL8D$Mf7 z59RKrD+rdr)Vvq7!j?{b_qh0C0-v+Y<#?bFpF5FWL;2kA52Ri(y6NbkJvoijtlF=L zw%;g^>Os*fOIC%&5wQ?-7ku+V;t6=LYCOp%LDA_ts%NMUO*Wjxw2v@t+RND^YQAFa z+G!#%%Nop?Q{Gdk;qhbg*>-#?q%OM*!ATQ#6zG)*iRW>T)uQd&toW_>0}7F92qwU$ zWQqLQv6sBBx9uo6)hV9}t0Gb4^ryPY^_&3)=_}3EWSh|jV<+yLd1-4;j<@XmF= z0%SUeXiAEY1s{e<6vld^ULh=DCI0_#^^Vb*L`~c1WMWTjYhs&|iEZ1qb;q{t*iF&JSy@ZNk-y4iQdXI`Cj%&Tdquhci&_-d1}2W zm;qE>S4MHDtFBCf^R;5sOcD7uz6in|hH#0j&?3a0jQs+IsGRyJPg%z!y=mXy$PX$= z<;mRC)P&?jz$nxRtN3hqef^1mt-YL{T{T2@C)S7@M9Ek>=(>ihR(5DxW<4~YWZ3*0 zP_Yr!{X`I|7FP5H*Z!qCs4yR|vG~*k1L%`|w@~*tysi*Ca`VyNw-K=Q@1@DzXsOjQ z`zb!+4hyU)&OS&mH}tqz5_laG*Ny3|P7i;I+mX`A(cdcML!(+IvUqZ{nL5yPa9z5m zAd}ZNTTR$RMP4o4U-I_a0mFPl|5;dS@a%PwcV6#Ma!Ywf<$y?PF39s61`m8l0oY|H zrc>qZ`3>Vx@0c~r+BmktCyGn(awG0K8R3=Kq0x^#4TF6kHgZx|!o@{3821vQ-mrQd zxhlK$+2U`QK}p}*d?yL6o?=3t2=J?`n-QSxS!f$&cvU$Q8?<`S)I09& z4n{Y9C!$VfrD-=swm7f~xd;U0Lg>{-u}UE(ysFxW4~Ze^Wzt}UpnWDl02W>Oxtux+ zJ`^J20=Jo>8Fq&Xib!xR$)@edGt)>W?d!^c-H)!8#j2Aax}_DdSX(*(>BTpJ`skJ1R4s9&^QqJuAJez z*|@63xYeP4F5`vchUkbFIr1tTfmKl}x@z04Ev=6@{5Gn0EeOL_lH8v^voI&H^a^GQ zJQ(NbxW8er(I1qK#2a5>#T$PPb5Glo7)kcP3Sr%*g>SjQ6CqI_fWJ}JFc>ScYU&N+ z2Kwl289jMw3k0o(JZ_81=d@h6f%^f^0mWu<55D=w(5J!+hVQp7(c+x07c^waH=qrtR&MPPSz0bi@pHk!5Tg!{20W;p>VHRZF3|5Gy7eV zANAx?(mZ)FN)FAQL+FsC-H0KhHYJksBmNBprZ>2M>?eX~&(j9CfFkbH$deoHncenO zPHew^1ZO75X*|NPpT^Vt}GpfNcRPsV}_nmZHa+6Xr~;2y)3 z!_KS&`-uZ(J~PCHWb(e&bdy(fv6+EVGG_~FgTW3{{K|HWs=5TyJiH%^)7ieFpVAIE zd}a4+fMDv|R`}gUw*Q(nivAI|XX-m7Ppqiak5r!tSR2 z(p+S~=zI~!<0ApW`5N1AuFU%nUfF}1jwpuYC)`MwXq#I zc?>5Gx&;G-;kbhn-01OxZz)KkE5Z_2#(@_4y8{ViCl27YI5#c^Wn90wH7@nTAH+u8 zy~VnfCw2K2Px+zs)BD)CrZ$&sGtDe~*1vNq%W-m$~*0viQ@&7}BuozKG(A|QGpTvfEpqEaI$Ix0JL}g69s&noviwFcYP{s3K7UwH^qE$ zb-sS8Wp(Lp0XA)y-rg<_?{81;@aaDkDs9U)w?5H3J-qQhZf=Fs3!l5=Z+=HPJU9P# zZz$L4dcNuw%1EKt(eCuJe@zxPc5;5Z1qV%MF^C(fE2Js##}H2zRYm-c{H+VU?E2$5 zi|4I)xZa*Z&o_ioj)L^{dJ0ha3a|RyJBVPPIRCBHr=rF^!_KP@^COD~P8F zn-inO0segkX#{-bvv+5S0{zr)EZVnh3Hng>E?nCAJq#GKDJVnLNW&#XzubW!30T;J zQm5t&h}44#UiRKfY&~GW@68BzjvG{t+F!u54pdc!`iNf% zx=;K5BX1SGH$2-R$G6;OFYx^SSCsd{uh>}y0Qv&D&c^T9-+FT`tOl~iqgSq+oXG&} z2_tg#aMA=K@~h=F=H<1i0Tx5yzMlv?h82fS*N*DdN84mngtUmdiABq!{f-@CC^{nU z#WQm};|X=4xoJ$zYcVqP1j{%={##Q3Z@eNP#@VDcs%l08VoLeaGQon1A!5e{mV6`` zfGOfukbI&MngRJ{^|UZ_y1-90d*NMP}H_1rn%Z8@o$hc0Em|#@@;&lMQ*{7gM2hbx0|*hloi8X4>DG5Rs|*Lc2l_?aiuQ z6IrvoYP~)0z#I+BX)EI1F`*zMBuC~wfI4ybkNQ?_UAv^3Sd;n;`9ks0pA%Io6g;1E z7enjSU=Xe|i!;5yW}BKn3%Q+gW{$|)z{@V^UVj9}n=D|xf8loBaCmH3+e(8n%Vu{- zks_Adqk)&_(~i`Zik`YA`dsQvC?sFUqIT*y^&hHUPjVcvAW@B>>7^kwb2C1H0GgF; zY?z_(wOyb&RwQa4-ESYXVGP0Z8AOhM8P!Z}w~`5_j}a7=EY1`cYgXo2bK?9&Zje;0 zH^=$Ir=5=7V$p9W5Y^EXIbxaC(K86j_mJB(!EpnJTCX(<;_7H4B0>1fo1C!CC!<$} zx(B6J%=78~QM%TW_fZ=OGTcG+3E<(TNP6XL^_eFaHS03TjDdq<{8<-Z9pzs!VLxe5 zdX3)6_*%a7f_~#8Nk9rw`)i2gC!p#>BdA#osXHX%D=0dpE9C~q$!8gJ!OE7wtJDRW zH9xYydhPH_Xc>yGvxJvRXR2Zx>}io5@6S9*^Y*o~W~JOnv;w8UQM+qQM*N z#Qq^+a6L*T@QzsLY6e@Y*j_@lE_Gm^IOsU4YUG&}1SObJFOg!wM)rqsdW|5~Yj!Y^ zVY&=*pU2L;xy_#Vbz=TK!`w&AxPYcS{QTp{UcS@B4i=T!;X19zD)$$%Wj14vux;J? zP8T#Y=IDAZ|HfKw3CRqP>w$ho5rr|MH5>k9Px`r;F}}BYngu19X!&Q4{kc3z zaUuu!B(RBB>~9uN=DObfMNXL66m>^%_Y+#Yh(V^4j|^Vll~~#l@3rxnLf5kn z`iibP9NQI+(k~N1V+x3pf*1ILCFZ#m{^G(NMYH*vdtcasAmS9^g85SyGC$V5OdLcO zqsqcDLk=eO86SZ1>hRDe*)51^K3Ve5TGsc6O66X_L9p+6&{2I5Bnm}d7~-qJhnSmh zDD=ooAf)-&E0RA^EiqWe$WPNv85B~dk~I#fk_wJq@;ZTyP^AzU?@~EC>v})CJR;0c zj5U!VPzW_`34K3Z2w5mizqk9>kE3#k6?N2i-_$i;l(96Duiud^>n85NsL z!Wz@W*9L%TUnGg@H||q215Z6k1P>*-I~o|A{Sd=5))Q?!V9W~ljr4~V{`mB(16b^Y`&#vheC%iM{gfos%JPAFGiFS! zVt;~E0JVngUGOEs5`$MW08<2Alag-BmK2Q-&KFVmWYUT=pxv>p!I%C#86Q-?&ZD%!0OA_?IX z0n9FtAw6O@YXXvnK9b2WXEGszkn$vm!HE9(kk{sC)6ce@^n?{jOL#ud`ShPRLJd*f z>wsZd?29rm{P>Ll@NqzwzQO3;YjpJj?WNsC|KYEo7!kfQ>^0M^Ms z8yc7Hh}nf>7Q4)&8LAjd&lZm#w8F3f15FiCS%nh|4sj7C=ju4iQ6Y6jWyyR=9q>INLz5|n_R_l+0h&DMag%pB1Z^+*wn$$6!FMlW{aK@ifZ7*%rPzX z=jbJ}WhI3ze9w3>>+bS0+2v+eKrf*Mmo1vyU5~&R0~@GSL$gRY>bJo|vwFDsynsN_ zA5jX!Qx+(%);v&joO`^tv9_+Qo%*COtL^xiRm{%M?m=TRVNF?Xp2#??bCyJtBmaDe z;@z$5e{UXFfd)|5W}DK;`zPyUv)8zGhQruW_at)VgoV$^Gy~mUQ+wJrhHj$YT zRGvwi8o5LyS8%@lXYrETQ#F!g|HzSg1pFCsNtNH}tvmf33A7-;m7qe-ev}XlQF=v= z8l!DE@%St6G#(J~U8@D4=Nj+KGF5{9l940`Hm%RMjFi3C>K3;BQ(i@}c2nf2{?NFF zH$hWD14f%Z?6Jj-C_=RXh|Yqfkq)2X*^ZbDz+Wai^6R%~b)RWIV4eaMl~kDykeUvF z>tggL^JLoYTl*>GMcZrgIU5t!dBgV<{V7*E%~L>th!in%j3F8I$+rwH+C6SjJA1Wq z`y$d^PWBY(!^iS!N^qYhl_*>1OkvIXrbKPO$j;T%p=e#Gbhc6oD8?kmeOHvGV_Wpl zO3Ac9C_gCH*h-$}Sj43jb}hR(9|o|=%SH7oPTulnHQ z5;rL8RN4lpo%ne1^d_*be##DMK8V4CB$j5v_|@!jrbT(DoCDi)vAJM1Fm3H2&Z)1O zSzjEg?~?5MqvF0sOHa$5Cwj-BE%&Ev(lBuHMnrj_yCY5W$EZ->pkoP@dbE0$9RJw! zyX*v2tw)`28}PYVNwNgq5LYE}I*-i_fxOdVxu^qB$exqIxHJJxut#EAlA@gb?D6R2 zl6BvHe5gWs4w`oQ>?t8EhU7DOSZg&7x5d0<+TK&MZ=7a#xZ~t^chy)G-S+nyn~2XY~UcKT6h{ zm(vq~u}jHa?E!52Ia5`nl}lhu2UU>$XO`#5vF=px$OO8ad5V|Dxe{ZryDfG%7kR<( z!z-QQMGUL#eA)InCRNM}O*yNf;nL%uyM7J>rDIF71=}QJ0;)Gy3bnaoY9|TPSO^EY z+SDIo^W;SQ==wK`3a@_BsQxg4ORv(|z~BD>lc2f%dd6)6gyS~{Lq#D6?^Aq5ir#cU z9YV=gePy~5X8auK2-8{4WuVuP6Cd(^$IMuKBxfdx0BI?+DgWdZjKXUgxT>I*v#kO7)wEk*(KV6G1VM0c$DLe z3!v;X&R|I(d>}}p+Z@rL=u&?ILplPOsVnA?WZZS$nNmqkD7A&tKv{oN4xiU#@)J;k zOOu7nzndg-UMz8C(oI!@=r7H|7P_JJ3tu>eKy&g>wf{h6hK|L;>z3=WachMwPrHm7PJA7|M>`~ zxL+*#gTTR&9x8hKWs)tkl6uQX@3!mhCkniQe{{}BRvtVIlCTy{*GUfcsR058Q4#*K zlf?MlvJUq`S{w^$?G9Lp-+|qwZ!{xKK5(^%`T5|~=yMkM^d&wf36L`t0O{eU( zv@!`>P)NOPM~KrmVJ#TH;u89}XzPF-z~vYl`+Eh>SyDT@%S~rQELt{MIn^AT zaj1#dj6@~~1R`2kIbFh>o`n5P*$cMfcH-`STUyvd691NjCOJyiO93G^DP`G3LW>BS z2=dJ7*l`mx&V_=#jkEVNXwT(9?=bA2ybjzftmREe*e!VJpDo7w#760cCO^dn*XDQ2>zaKN$`Nor|3tF z=8iLeQFWP}}2OYoqI*!*o&diz}!lsSFY=ya_Z977e9& z`RZEiHVs$K>;+|0Y~2kjN_20*w=)Wg!A;;1D`p_qBWqA(U@N z$-G*nk3(q1$TXS5y+5mfZd zV;G|6*Zu^2@S*TXjs@3hBt+^t&rcDmSe7AG*a&0ySTv+F(Mtp#r8;#`DL|nG2Y`x2 zf}&c0F>2`FUjd+94r)UKu>;Wlvcgd(-`=kWYWtwa$^AL!j2t^N6ATeTd_^+IsRmC3 zi`8ot969a|vG{l?2XdJ)(X0KCB%pWgr3oO=3&5J9iqwEu#t^VcV)tGViBIbLalPO zT#NK9QF%xUw|KH<8zqADQC{{lF~k%=(;*9FDvK!Kpy%>m-vXDJMe@&3}}F`PP}81tnLQMi5K77Q)LxaP2!`IQp{lVb#lD3 zXYL!{rFNSPRHLQ~$3=nm@vQun3p3h3vjst!u5VbpfPa0=wje?8^xt zr2en)(u6s%TG*y&l*|d^MPa@FHLm^nUs~7F|apSeg5=Jt)xzS1sAEe0$B=H+Ajl zAVE6C;~#;v(H&~cTZ;O)qE4^dpqn>A`|3v~@kS%py3_o+4BdBRqrns6^#$Fw8|)4( z{$n>@51#SAqtU^xWx>ifU`zpb48%4`|7_%=P8po{!RzoHX&ap7x0ecj1rPn+;L>JC zmEm$sQmi>M|0nq-*LP>$wkfB-KEp)0^{Z7RZIo*nHo@5Vz@Z5O8A_GL*fK#$`Ry5D z@Obb~*6vJ?g;ytG`(>QnWt^s;U1Pt;NbwVN#VS|{m%|+8SwFIZY|s?|_-q4a<$Z)d zDDwhNeYtawipcO3`Zfi&guRNhq`BjXFV-`lwj zG_Cth(4*}_(X(hbBKFfVweQB)CFN5c6s%Zv4(vIQj~w%AlXaXbe>c{9EzpcU5oRrH zpFDE`9|6_Y>Yn0EU*Z6eYI(8{Ft7^LuKIJfvS;5fx1?PEFJ?4Xb9u3j7`nqE`u@3U z(gaP^F;^0FB6?Qal{}PJ->F#gocS*k=AR#ahQ2roE+-;2yY7@=z+{>@2{~fT+vQl8 zUcb;R%Zg}c@_Dj2Ui}heqocy+oMbKLAK@f0QV{p0e`zo%7K)_-p0 zbiJg-S`v0viS+Rx&_qshnm?qC7Wj9Tvp>tYq~Kn%UAj_kL&qB1ptT7WY_w{oT>$$_@9T zKMbA?E`xzqyDy(L{{}cVpne*V1<$-0J^-@{oq6yAO{s$yu@Ch@|#~z z+PP#+xk7(Q=l5wy5tlQ|o9%;0LtULBE&83nBE@2#mF%`Uz4JI0W+|8T5X<&PgBUp5 zsCh(O6xOW-Fss?+atim|*rA5BL{xNBFSPCG*j@uGJS}=#l~quLA`B`3O3ee45@Ssz^o8?Yc_xPV(&~CV z)sya4)R|sjSf6xdGq#v@bbc4x&RQaRP2gOhVsuc%j{XSD^=V^ktHw4HG9P5tkm0!^>_{ke-_zHanLHALQlS{NpwqHe+216Sh0PqByg&QrbqTxF>^F8gI)EHPjB(t#ggEpmm9!Ywh2jWHdh)1DHXZTg$bXEbuiC zqq85`kmyAO7ngOU*57~*{S+o>X6Cf10A@TVZ4pPohMUeMq|pb>2)5GZ?t88HE$azD z#b7p<@26ziAo@>kXKkHbt|h^=<_1ud56{MS0^|8XHPS&%t?yTm#rE{9!~a#91eYYf zHY}<+4n;SGg8oO?2y8QpW5O{4WaM+Bjy4i9U9+hdUp8Ub!K#+h zDv6M-H0Gj;stWx#(@$E?v?&_$XgGfW{FJ&BE>?PhTTgEZ_Ine#3@1v~Idj%Ro+!v^ zu*iY#`0K4)1^vlQe|xFnVCs)Dv?U<-vY<3)RMqE~-xq^@czivWxV;)qotG9E|m?;ZvgcK%jqe zu&21BfN=a$G;=U^*LNgT(zkLow$yh>=|}--hGzffjA3JDXJSb4N(I6C|EbxjASNKJ zDd1@!WIq`hQ;;G-Z~$zK9RF8hPm#8C3~p;&Cw(mlPhCA8w04h z%_IJr!j;sOg@*saPnXY+u3-ZcQ{}kcit}-nB;{Txk&aL|qgspaL|V!a@rlGeBNOfe z7A$+rse~-v&)3oL?dpt;iRQr3Am45#cWwX%5&`q)p*T+tP@E%#QSn#D)`TL9mu{v( z&s$_peE(ZyhQe-lejK zo6^6LpzTTY@>nV84qTosxDTScNjKel`!P4oeE`kjgwNqQrrZeDD~RBffdJ7Fxg~(m z2v^JSH+bg~%oZ;B**4`K(ZMm>gfVYQAZ0}it{(o*J-&h-hnuX>?JP-*mfdC3Y zwkJ-=#n=u;GsqA?ylbwPiAqS6K}yEQI0E@RZScsTi4cp$jBXak<+t4wYLF}FPpQ@i zqK=Wdm%sw}6T9Y_JMs~UkrZ-3N{w*<1v+TOC~;>#?Du;Hq@jZhh3Da&pbavC#-6D0D1wwC z6cTb4WA4~R1V)4{f+`LSH1;E1qs)QJOEK$53rR}J!$OfO>PRTo9TfSdgYcp|=D8(q zq{p*+`9D1mfSiWQVJOfCrGb9`KPe%`pb3f+P9!lsc=0e;F#kAZTs^?y#4%wwAU>aKegsqn`ATYXAvBVFF=%fyJpR2o2NTd;%s>Y9eI?l1E$eI>SKs1bTvf7lA}D+Zl5vk7oUkpWER? z-0$&BPNem;yP}akG3Ws^szpo$!A%49zqdDO2ceBtCMbFzbfW-U^YdQ6fTFqjbk0YuX@#qm zBi_5!T0f6hOkN<1#Ymlw2YGD(J7a!PwsnV^gv>TsJ!g{0kjt>i_9!_nPHv1}-GU!e z@4rDLxqzZN$GVqVk`bw?zI3{MG$DMDA*6Kz!^;t+Kr}#qoI4cKZlLs1Ew6-mW@tEx zB+?R&DF?yW(?DG)Qr$cwJ=v}Igk(#r1DTWmNU{X}?y8nL^eXYJHfO$TTBF~4e-i!} z`cZ0Q-g8VVcIw~gR_tT-VJ-OMPE0g|zh`NUy(D+I^=v&#-$e2dyNT{$eG{gMQIY7( z4fim^@9+RpoM=uwCM;cvAj;a+diCjhZ#vpEH+=zY9s9y)Z%G-k$Fc_y6MzZ|g6s5wmShNRSbGQ<0@)7wzYZYB;wd4r)* zS?-tW;4>~91~C*^cM~TA=$C2bVc_dI$9+<(JpiP*5vnAw8)jqhWBPm2S_533nEAHt!<*uGHHHQYFo_<+=9U&jQgZ}v;ZC|3vV zL>~}kZ>j>Z>l*QOg_*uylrX@RNNf6im9MNeIu+k_3Y?3)(nAC{oQ(RCtAh;K5%2;K!pV z+Jq}loKR+}%f?ZYR`F{xwjgaEUT41vb}@XGc+&pdFZ+H7Ewk>4dq}DU==5G)^Th2U zLuB}u@*p(h_nN9&Re^UJOcId#C1A3xQq!_8X@L)VlT{w)xuZ`jf!9%yY zm@CPiU{toWaj%8saW5k$<{F|6VFSNdTGF_62BHuQWJe-cj5@{!;yOuD_1nLP^7`w2 zZm{g({yRz~)u?YR2SWUPq3RJn1GLiHP{+t71-Ui)M&q9-b;cB9(&69S7ROR}6E;rd z(J+6UH?|T?vmgI3Q?MK@u3MG~2q8Tm*I>~o4k>a&X6@I<-6O!~lbr(SLOl@J#x zkvbZO7w-(I-n zf9V>5VzNYOK32#sl6%bAUmT!xMTB}eiG--g7#R)HCy@+H%WRFK07S>W3P|fc8r9v( zxpAdoaI>hfe^O7JOlV-IHl~@uZ>$Is`68)c zrHGBZF8OBizwca%T8$UGdw4!wUJkeC_`JQ_ zJzc(xH$P2(ectRWf2Uc0dZ&L`w!PgPg_-KuemxHZK2q?A4_%Nv+e0nG_o;3#?>^>} z7H%KgyJhOa?J~+rz9SQOdbvm6?^B8)e=&CaLr0UwYg!ma4ek=G5ACv!NPeOZZUl;@ zPqxycK%yU2ap`FWsG`LG^&Y}~lH+neHd0+TLK7-ZL*{8(1V~>NjFkLln)Jdx<3=D> z{A2V=$V3$?#hl~LQl7CPIyOu_6|Io+Fp_miEkY{1iztn4(R z?6mIeuFhJ2=^wmQYc6TSXsLRb*kP^ePwx34b$HnlHE5i|oD=#!{`V99t$!ca(_d*a zw9UpwfNRevC(ocNy!~~Awd!vIQ26oWJ=+-BuXQ@bB-_9-c0saoB4@A0Ea#(eLDO{B zUZ3Z?C+j^bN*H(5?aVW9y7bPeh;RFpw6*b#YHr)WL-}ok3(H#M5jAhLB7zp@rOwv1 z(HHxDgQ8Z(^N7qV5xR?qY(~!_Y}iJ;kc(wN*XT25NbfksQ=vwhg0pI!#I+4=L#H4U zf=*?|=mo4!vkv*{1>Y+5qM8}7Ya`b?;bAn!KgFU{s!^$UP`i`r+q0{5u0bQ*4kcKR z>?d&gC;w)b<=VGfozk ze)e9~c9x63bb=^Qkp9x~KdxOQrs6c%-tqzeT)QpDT-H9w4KAUuaX-N7_a6^D`==ASvDdR1%oC*9>KTG>T~=d#m(ZD5<){Zl-8 z>#6?mIp&-vS|L+SG1Qu1bY1v+)-|W!Pv4h`< zRCV@ixyUAk4hPNC-sd9Ub)Z&)e=Q~zqcg4p5d;37x(x0D$S%A;>4AzEqAVxdTHj}O z>3WzA2cdpR=|Mo1;DR-~fab>$mX@p_jz}BPiEiY^0zdoidq`V^DW1-qbR z@8w}gd90&(j-}Q#tB;xv`Wsv0Bz$>9b>3a)jI}9N8A5YQarVvnMF>i|rPnfRyL>%m zhfgTBt~_85ZQ*&dM4Y{~IDhC#uHH0xBM}E}F&#>BA%!fN-owc{4#)FY;qltL5pAnIG@l%W07K}XrV$C&o?PcZzGGh2y*GtcQiqV1tLgudF32Q#tGe2*)}?|n zJ^Ds+6Yga&u~pJExuOVg`CFP=HpgF3z5$BP$Mv0L%{fXIT#~B(y{vEI=qS>ESxm-R zIFFg|q%4JaFkMJA_0Zz_uD8N<-*fzC$U{#xX7`Zs+x2kqVZA#p2yr%9W&n!%X?6a+ zn7Z^P&{+ufJ|Jq*=4Ggsq~4moSk8nd|J1*A&D4XKX4#62+T`pb~R63i_ zmJsX;B)F-mFf``65>z^CQkSy(FAXeH1WoiB6j94knEL+&Ic!Ki+^<^8W>w#pyM^QB z$(y0EsG~`rqzXR4(5!}&mFtaOtO8oJq2UG3P-!^PB#RYsgRyl%$W?pyQ5iTpIntsR zez(A+XNHr{mj;tWeWKYppvlPi&2LY&oQc8bpP}(Y(M1w0Jj3uTYVJ-^yWMhSbFps3 zh#WU&$$7^#|hi=x5b@!oX4K!_NcE((PY0>z_)(d68UW- z{^)&lA`-QO=2kYGw^%oYE9um}{QOM;^*lb8mxA7qxKb2ILs=)Fr*5G5@of3S=0$KX zVpQMhXjwNW9wCs;G~KqFHw&TXKeKD|>-A-?|NijqC?@9Ws(MQLyXNGK58lyHakF&2 z_SU7NB8J7-g5*}!KY*00J_-(Cf1`n-kntwNs1GE~O@JIPb`;VGUC=c{4#yrekF5(r z@G?{m2aXO)Sz?LKldJ{zM?-h}VUucWwb6sE|8S%6X2rr&($K@W%Y}m0Rc`x5eIsK&%9Z_WX!YHG zllbO#TOSQ{0p8U|Q}93C?3?1rUP!dfuH4Mq^C%P0Bs<@qxmmbc@SnNeIugkGEZr>7 zed2u6h@|ZS+{*aWXmHTJ=n$)Qqe{sP#Qn$y#*yzIH;+~yG!>m0+q-QnW9$fB13_C! za7XZV1TLWnNAh>K{ULQ7la#jl4Tu zi4Pvmr%K^@B9$Cb#7dsVo&Qcd{mq!q)6k?MMkmdOI&0A*2A?-O?KvASDU}ejZBf4Q zY3%^uOt?@b1sXp?N5}nS#17p!??AXPRpBSc%?SZCd4wW8M-p2hiLDVO)aRb0Dj6J{ zq>sE*u$$QmP|#hdS#SLtX~B|BHBoYY!Uw8Z#q zQ;=22AMjN559_kHycgPK=j9Z>ii0@J-7HYb+WP_vx6O^56*y9S_%674cvk%yCEO*b zqP>7H-DXyztdtzsufWT)_`ZXLR}{Oh{_f?w>+Bo{T|*W7eeNhj-lGd0mHVvS4+p?O zjl1To=^%G`Wk=Pq?9t4HIE&tKH`&pdc*3+sKVA^mB4=V^EMr`??sG|_$>=}uqH%?2 zB3 zm*GSkTS#5XMv|h>Tm@i@YsS6;fZxHa?Mz9Q8Y;Pkrb?s2mTHx-Lmlk&Cs&;%$O&qW z)kG9#Pi*$YV-FwUKf>%9`LA=jE})Yf@9i@YdsB5*IbGxj#h`MCzN00;e_U{4@fI+_#XIjK;((i%>zd( ziaii)6do(`B=IIsWpyXdzuqIKm2Xb9L#fJ!cx5B4_aGm-}6=4=J ziaW~O&WuK8zUA!b@C|$Y^S1h0k+%;Gcz@m7cr3H{^g4XBix!JmCG0x(xvkOg%-0j* zQ?{HxNZo?36>)iw%iog#P`zepLEkjz2(X+buI^FnM5p}^UTQc2d&YnK2OzuAt+~N{ z>}WOizkzW%Ul^6=WI5j&*gEo`R&zVrws|#(<$SV^pRx}c4Wa(Pnk&!%$x@JPe}7=^ zUa8`6{}0*!K&opn*>5+PZ-92@fxAXUzhap! zI({y?jE+xPx~;fVw&2?|_%(ja9#gMgq&yU5_pnpM;U$=LN7|D$w3S3Py`ro*xa_?c zL>B_CsUB9er=mBfkG8*d6{xT9_8ww7`c~z)jEeer`6=dASMF6f+ONDaQpzCF`?*BU za=e@a@9PH{p8T-x&!(6ZR&M6(X_OIZf*T*szS@Up7(IN+3iL)x)WS)Etm)HK^-8l7 zAPe-w`GGQcc_7J={$wAST)HqH{EoHw|HH`u%EZBu;#&_wglz6;_@C6H|Cex?iSxhr z2~+NBL6AY1|MLuU3TGV%`_JzkjQ=R0tjvu6E3mWwufWOjAAyzp|07S};h|S@w=<@f zHLy^0vZj|In3VpXucD5*hl zQFF8E5Z!U6R9TIn|3JeoGZ8ZG!x+e)7ug~8_^UJ%S{P;E7#ZAhEDyUtw}|W9CTC7+ zZKPa6qgX^$nr-%g0q#$w4nsg@OhuZNGzO7?ITqfgAjJuYa4_SbEM6NHznEAGrT&T&VVXK-6To4)Ph~#)wC?pz{2EEdM)0KF0V1 zwzXs#IxbvAn-9GkhA1@^b^NMJGfQ>2>G0vy!1=|?`Q@a)rftQVpvr}R6T!6{!?uAx z>2quH^gRn8&p-3{v<3K3&eCk@+gRRnEV?g`OyH6rWyL!(q{_@nHGUg2Eugl{l&Kc0 zr*11k8@9jo;*x<6uvr~=)nBsUXOu*@OE)B+tPqV+A;5BcM?IRVW{PEpd^;Nt*pdB@v(K+gXR48$A7XP!QBz{?U{0sDN>*u6a9hdTpfLT^w4p_^cpo zrF)q5#6HWyan6~iV*|p|_daG)MzUJ%zrf=_py_%j`oFW(?SG1nZohDv`Xt_+c%qY0dmM) zcWpM^&S|BvV;X|QS-8w|jB{+iE6oSLZT_ZsU}0}98sG4zYfk-p>0D`|9CoDAQGOo_ zHX8dAi!eil;&>Qo2kgWD)8*5g6OCxS4gb}%@-G!Q@(0o@@sMz21m^Mv zPz&J?msq4MW)1`2A6tL#o+;BvP(UdD@A$je%AB>?3gizl>jeePRy_X!juqLO96kPC z9}B+{gStxT57B=Z+2QZojGj!)x+J#H;N77!qw}^8X5I|vihn#8uJ@(YdRuQyYttFBJzLf5)0U{}1!`?_y+Up2s$QbD%v7&YTk@$FsmFf! zYJE3+eA6E16Z1YJTWko`vD@R)B{DWLfC_`>>$Sn@J*CF>h zoE;8lhl8&;kU$B95<-taD4`M{ za7f^eq*ppeun`EP(93@#3`R))XJryX^dR|>#Co8MkckN)N=U+NQT8At84R)QWf=OO zR*p4L_B9#e@*w$<43A{|Tp~0XOfr~c>a`n;Lx}!wwI7_|Ao-ERIFQXCnL#S|ninz1 zAdwMsjC{)({rL!NL2L9s0CWN90?-9u3qTft zDgaXeo&YpK_y|&5`ZK~RDuL0=_t8NufpNx0f{KU%>!zS z05=Z+D*&tju<+rxe@g8iIQu8VqpvHN2e9zzs((!CUtRiljQ(|@-`DqB^nNehZ+s7z zneZ&UO|(re+%gqC;Z+0kdclfZGWn|U^;drbe3`PCmw`S376LOdmw>YYGy*m-mw>YY zGy*p@mw>YYGy*sYYGy*s_mdXPrx9Yh8TLA(%HT|n;K^Rec6mpQTP}*WHuP7g_(Dt|DGuKoV{S_ z^{>y({{ZFR5tUizFKTSaNgba-tmp)hcg=!^>lbIPvUyQ|3FOrUO-mc3ElLBiwSN}+ zEo@lOw7+zJ<`!aCEGFtddhw#>rO`gL0rg=azxe8=#SgZf_=sp?J&`q^#9WPh-M0IC z&zPQ4@~O#bA^{J**Q<}n-)cLx>Z|Q%ud|0X$OE*BNXf*w9JP|PhOH-sOv)yIr4SuBW4ZKun#EI13Qsb~T!4Ix z`bYQE^;hT`0IJ80Qqh;1_mXlXGLaP;N3ga4v1l}kMe`|p#7rsO5Lby8ccI4rL|4+c zfUTyfd>btnD9Z8^bTwqRp!Q zl^WWApgd2rfDeFvNPdsD8j5KF$`7OMKAEUU$e^zchHbPF{QFSf2;Kw8Yf*j>^fa^^ z5U0(?J1JY_Km+)_zi)i>c`0xe#;8I*8d!-jyCEM5T+N=RHSGE5L#Rhiw_*I%f)6Z@ z=a;}HD^XvHc0EzP4Rj9lFd$C>dVm*w-}wJr$)LOs5B(1WxjFjHw|Q8b`TxMHi4^}k z^ufA6_Yb^n^!~qmoNY7@m<{y&tNTts0uqpb1SB8<|GB`nMtA?vI{dSsIREG9nt%i( zAOSxlFpBOr0qvBCn+Zrjmw~6`zXzTIz6Siu529Ke0*=zg1%V3iDt;Xz!$$u zwT!C8?@meCH2l2ZuPV@gzv^bl)xS2;qB$`|yA`BHiW`G0*9r{PK& zJ!~kZdiiP^&7P;V(igOvTWBrXjptRAEMHG6g)X{2kQa60_nqV=&~Ytolnw(eXNc0$H)hwenC8c6TAgvd7@KK{P_ z`sWWASWq}<@Q|XR#ec(wms}jHFRvIq=900OR$ex4{Di8BlO|VBskyv1IQ5EYb^mW` zbo>8JAofQJT1B!`BzwMJ^p7HWBS!zPUg5wME0;E3y=3vCg$w4-n>%OrRkNCA)YV>I zGo^aM__9Fhh>J^x4=Wy8Gdx)%a^_@bWoD$O zbxU>FQ<81gB#YT(G$^vf8TGC3j;>cVU%e*#yq8?kPn5k4U^JY^sMl1mMqenSsr9;; zdZA0R8)GDk3-;F%S} zS~;0)P)f`3mRD%m-g2RVCgoK$%+#tT)>f1|J)U5{z8V|V=$)aFcchl$*F|WQK8$7< zr5W{M)Hz}{bi3NxcYo-Pu$^Yq`>iv*GaIJWYEnZ`jDO+qW888r^M>PD=Zfe&byV%@ z^J|?_s3L2QDvF`dYE|1ZvG)90k4S?-^ntcKZ*+ZVG={zdMy#ByVl=)oSgWy>7*Z88 z5wnWTugO~>IQ4T?&FmfNogJE6kEO{8X*6k>r!6NZuq%3uaw^nNb*s$B<|L zlmsdKq|4P%-$`qJzt*RZa1rAutSNLHp_d2u>wkM~n0vj8?J6>ukE&qXhTyP#nBU_O z3w(PxKr>L#S|--U$|}upwoxG8AJllgsM+6HlRib%v~<>VHLv%=lRNaVkgl10U0*5o zjBXXPhiNS1zo~AD)mKjTR!*E+t5$^S7=zMvGVAKFzHr?hUPY9%L+Q`{-(wQ$O5 zU4O!&P;1rXJbW2+r=A%$n&6c>hpD4Ad;KM`G-&a7{>et+=o!&U&(1ZAtEmn1UsxV~ zLHPpptRV>s%RXLNJv9`vTu=vBiw!t7p26d(y4ItP(r5~HW*)x6(fvaO2Ax^}CL1LL z;D0ezym*12GfoEq!aMu*9gRR23XS%vqklv7p@wj@WrkO^dqcbUZ}@LQi!16o9VZ;! zeY;Z|eMb+2OYq0r1$lJYQ2z}d=lqG;6ZL2ZIR=+$QUy&i9E6Xw!7jI5sO z`ca@bjcoO@H4|F{Y|Z4UwY%&%vDQ@AwsFQs)sGCe_C#InE)_?G&gFtDn4+MH0)JI9 zn5K=Jbb05l08xuxE9(rs+!$u0^GuyQMvY+}IHUFvtdu!h(dQ(c z9cC@9!voG;dQX$$k}Z%Fyp}E=G=CRj=XHefViTWoZU$4P*0zrz^slFo7%4zRS}1Y; z9?}Do@bk<4wN@UgoD2^Xm6oAS%X!tRXs9u-Hr;!@N6b#E@hD5$3YY4T{7*{Y9 zQt^0UmByOdSSqSmUl)1`YArK5Wt}eg#JQpsO?AI&cZnF%HQJ4xqg{>B1b-3g98PQe z&e5Q~#;y>l{-vwmI)uEj@o`GW1`SOMO@%*twC-ZyxE?4byMlTT&}5^o3DXa!M%)Qz ziM^zXAcrvNy|k5&_v<;+^U$TlOR?=6(yqF&IJ>JjT7Mw!D0%&3VFGi}x2#8->(u54{aqprV$LD#?O|er57Qfu z5m=97XN=a;*Z>uA-i&SZf^jJrYVC}e1;s%f5;v#D1~d~^j*p}*^k2{=Vgf^mLPugc zT1%B$A5`lRL)b(Z+o@^_a&;E2Pu>O*H>zUusY38a))1PEwj`F#sec&}&t^3=c|~y5 zgulnEFLacl9Zjy)$QcTG;X_a{Z#0C_y-zdv#)=GIi~Zh)CULWyB`$VNu`37E)vY6X zb5?jgL5T1?-Ig#MHrfo4G={{zv98_^OE^NQA+bkIz^277lg-&wSTk^fod*E?y)}=msX9Lr zPSa8=Ctcx$Vf(dKuPjTF`ih75pzh?B{8Aq(LEfj$(A^!DE`MtGWw~G3EA^&hKrZ!e z^LKael6pzq+lIRXVaeN`nqH7n)=yFqg7fuMMY;&M9k@>tuQ}7DT=4BkZvnOdw*&V9 zUjgE!5UHqDfs25ffyYFR)LnA5scw5&FDV;svoVDfDU(hEqd*CIW@6M#ngE;*TnF3? zH0W}Ivj}(#aDN~0j9wFvGTZJhgzlMbx9eH^-1!B1u_0ERR;L%+FAv7@aT8;C`Pi7) zu$b7uK{0m!k+Hm2-&mfSSI{DIi>+XPS%#E>NoGLt#Yh={mQolaH*Jy9Ndt1p5a$G> z)b^gfg3bFRnV7^SMl;DB-7m2=o1>u2!lV2&rIMSU;(sS&HT-0IvZG*g*`@ql+78?Y zl=!=N-r?`iE&Q0UInq+#X5c>HVc=C){~)BGVZsQZov| z{10tk_J4*)`LNRPs6A2-yrC9KJ=*dH!u_(^O6Iu3{JnP7@7_{2fWJx_P<(RmDn@>l zRA3db9=I520QDNE*Qf=!9=HXl0pVpx?Ld_u1il1(jRpV%z$&1LztV%@^B4JV_520oxyTRl=YQIA-Bgx@dO{mJay#;T)GPd%_MWNk zXqkiWgYDc%^MR$n3Bc*VbwC5($9uHRbf=<|J#-N7)^6TLf7SCx=phpY=DGvEQE)(2 zB)(x6gF>=d-R$E5--dfp6p8PyyFrP>_oF*NiNtrq3Q!{P&A%3uNPIKrf)a^u>U2;d z@qbOI28ATdA9%WFFL%*|c}y)!;n%@R*TG8H!AjSW%&!v+wLHXHnpn%ttYrmjDPb*FvKBvUaj}+M))HVXd)QEzqJ;%IE+`fUvRKPO z*7784X=W`x){@6sda@Rk6$QfF(>AtH&wncPti4QZI^-9RK=euB9$3@^pZ6dp>_d7O z7}ZMw2&p|{!r8eZ@6q0;G*<3EtY8tg&jB<%fMqy9M}aaH=m6a406IB<4pNYo0;dD_ z15X2^Km(+EK=E~Ynu0VRSPGmDyajj~XwcO;4dk>auHtrGF`;yRT=5A&nIFK@1AmW) zdjj3+ z_9a3$+t}vY<1R~QKcie3p2v#G$MTR5rDnZ6m|P~24$v-`t}q9A!nMc!Cp9dyHh=dY!FhbA`&HLk_Y3)96F7T)VTNqCs*CP&4Rt?x zP#0Z+icM|qn?<(MeUod9d!9?LXo^)_*^E*k#XZS4)qM&2D|gLs2b$66PIsy6N_R<2 zYOrXt(>(wx_+w-rDBIhm59-YYr^7vX%9Nron;qzD++eIVPB0EJ78v^)J%2{GvAfY} zOf#jL?51Rs)nqZ5Oa_x|;wCbsg`>v;e(}L$n!zqI@z+xs$vSQ4A{C!eiqOYQoGvA; zn^egwCy!*6+WtnWoS|x;P4jDJ$dJ(yY?d5su=~<=>Ii$5a0~ z$hv^;K2qCIIk~oN@V0H;M+UV5osLF9S86{IAI0oqe`jYZ%6GB9i7Z&VOB%ucUNK4V zr4i-9U}c!q=yIg8zd;VJ^EX}2gi~6`k!s3~$!&_s<)J;~dWsBkW`8r~>2i5yvo0qy zA=ld6v!cAUXHQ)wQ>A8Ira4nRU*=#QWb*QKnT!@XsLLG8Xc02n2wlYGf=I4Q7hyT% z(nVY>M;EC%Cz2l*S=%MDRv$@X=VV+l8QZZ=8QU?)`2SgG8tM15_Tj4ioT<|NK}szV-<<9io{rB z0%P>CNO$$B+Ex>d433%>%iDR91#Vl9d;G`@`{EJ04-fZb-GA)djjPL6O7aIat9PVk z1B$ACW&O%T6}FbBN*140#;dY!9`14OW?SP`cCa1Zk>p=`P4hLBRWYYL_SFmkYw0z@ z;IY)-{C$AB3N6r3-n^8kQtLChQY*#FZ>!M=ZoQb2HmsAElvELp?vFA1gE>qvC8o^52 zI}bqK4|zZ21;`7e{6MPDE%73^*;M3CvXr}xhH`gjuYW;5DZ42fn4>&O*|Lwah@u|? zPl!A+CwfBEi=2Ois2PqU(N=nr&7mi0AN_`%L96Ywi#kZ$s>Agki4I+rcF|v%%WFCzk&uHx(+(XG>#6j{oIe(918PTJ%{+xu}k2 z(5^XZ_M*?uW< zc15HV7E@rQ-c*d5Mf7WWo?c;I_6%R7Sd{`Lpxh9BmC|S+O@X$LqU8tdbAB_PTcqdY z(b18V47>bTSet%J@30(}&nB=M-kUGt4@g&&2_p`~Gn3}P-W$>T+i=F6+{zD2zmOl7 zzkfD#j~t68V?})QbGo0NVK&TEWzFnX_8NPSkK)t$&-uI3J@RAnAB+u{^_8@M?xe@* zbC$}6vWe^pHk&PHtJ#m)z3dQsg`MDKyqeGBr={7_66sg+NIa9}X8AT{m2$h`M5H$I zY~=Tm&!Yv=RWuR)umalulpes$cF|#a9e>YJdY36Ii6!GvnTJhbH{!XO-N_zeTiIi* z1Eajc-erHq!S*Tpn&a5!2JXaNO5CWt{AyfU@8S3H!+2idAM-DzOsNN6b_Yu(Qczk1 ztyW9x@$8V^k#pq3aujwhP&O!=m95I-%5Ri22CMN_To_*Z<`-xCoP9e&ku{MGk$<*G zNAw*^#~R`c!aH0Ev~R#O7wf$N9=Dy2Fe_}A!}_oh>@rwpI-ARuuWY~wCn=l*;!AIT@+xso^WCAiz&%{%yO{42>QB}pk#y3|J+Bh^Vw(o$)e zv_aCOm!!9(ccssyZ}3EAi|m$r$bUZBFOQL@%h$*c$REldD$|q~mG=!6!ve!9L)h>) zT#-f?tBezkb;fnZoyJ#9_3+LEw1b{L{~LYmn6yHwkao~ryim@@ThYt#=jk+48pq+O zd@EbSZ(<$1r*gevI3Lc&(;3+ZTR+D)^UwHjX&kF$lW8s=80*cDCT~MlB7YyClk#57 z?Pc_Qy}`3{46K1UAmZmfg2{FwL~>#Qe}lr;JgtCKbvPV?948agan z=xylz4S|?LJdYg)>vbIz;RBDRMfgRSt3gZ7y zT!Z+tR$e0CCVxqHV9#$ryxD?%vkg0^L;vp$;zM`@Lq&YM-AE%lI6H1IhWWjLZluV^ zC9)Xh$M%n}9-JlPd2QKaHTl7VB_^DP*P%+Dd9hCRQExFafEpwYFu zM%Ih?MRsns*cqjog-({u5<}iWo24t0!_hMxb~~Q};){-y6rDKUVYBJP$AJ`!g-=OI zb|>@XCsN~Di|gAzXwFj1otk&^l4DRWAD+UD%#3t9Kf3~p*yG|}H>}t@b=={|M0Sk5 zvwwHjhS1bMe0}zfQ<1+%OhWIgvA>7OJK?lO^`!B_)*q30&tB-O;hdEk=olrNY+v5@qH43kwPg^M%9bIXr_s z@Oe+V$H7@-30t>~t&1!<$?o1N@~x4DLVuHOk+<1xxS?5SrqE=E1>xdxLzq@WP&`CBbZE)#zH!+NS3sLG7UpyL0>rF~b-QFQ=8Gjhj(?4V zB3|M-%3=s*%Zu+67CByL|A6wxog6rTmS9=hD1cST&k@6P8|+ChvJG00k^6U0xz7a!Y!bEy3Wj8$U);_6>m#+<%Ew=&AtX$RekePX{qXtjETYF+9{UDs zPOhw^<=SkS2t+4z{}x0bTR6DcK~}+`467BXRq!Yu&V2~UAwCqXFdB%B3jos#_&&#fNF5}l3u1&fjWwl|WafAJZtT*^;hS!qbOv&j|smvbz zgsf!6^3+gf^zYb1NpboMynoZ!SRml2$!sXXsovpUC zu$131-)56@K(x)5@rqOGFZByIx2Fy%EXc@6Mc^@bd-U>kvu6|*3~|_f-X2E7lzB(C zT-&yEQ)3QJ#~ezqyN$41 zF7I{j9uzP;?6$0K-3(J~VnaC`I&mssw%bAFrYX5%qh<<$++0zc>qb5&@DSvW9mHbzQLivX%UpSb*RHV-qh%L;!2DGN8a(%#nImN*{$2k^AO6|s{ z@hxXdckEJYYkef zljm7yCf|^HL$|f5dsE-fdEa>^$GR`+>25sNVmBEK2Y+2TX)afe$(4ghY07a)wp@Fd zKiodS!5m?hwL|DhLa}znt(FV6yXCy?Zt2?Ywi-)w<`D#1vE|twzJgS;v!Ma2V@E08 zxEJwTxXgF+p5$ihTJ=p@hrs)pU&LR1cj7QDJ$bh7xFc2g1CrIr{r$-Z$FWl^zGVYu zr`=`mZhz0U8-5)=6LK@KbH5G^QXQ+i8oO33t<7mP+ITLG=8pN?nr72?Z(4l! zI*J{IFsV4F(>=Z-IMk3Kg9l;X>W3pXHI7N#g$zd7_)QVd%=^Wr(_8Po@z(p;u5Mra z{>W#SJo=l5rsY2QWLZh${+pkDf7ZO8+!yM0_zm~wCbo>Z9|IIyhONT3$|hGhE_Yn(lqO}& zw|~z~o0)NqZCTnXTPSU<^OrVDlGTz^ z{mIj!y>ETLtS}qemVJcnWJ^_pBC@9v9mP z_aotJF<0wyuQo-Mush*KK@pDF65&L6sgb=_TZ#p~vtxcrimSH_>goBtZP{5_u5{g_ zT)IaU84L5T)}ZF?15LiSvr)0Cq)Fl%?noOO9(n%OP33DeAKgR+^HL11M+15?g z$E+_{mCK~dZ1>1gDnb@n4U$o@BuPe`hBn(lNlud_S+Wtg+GL}&hws6~k+UrU3&}D> z=%7Uo^I15|%vqO7-vM!d;czM{{FRa`Uq70V)x>OhMT^*-8YgZvFtJfZ z3$`%W#5M+^4__wV0bze1`3~Nx_oEF|_5MP*2k~-;h)-xW517=+K`ei`)t|}GU~k>% zdJd4yFbr^eH1)0leYG;+CtlAg%^9}5A;WT|rL8n^4T=c+WP@r}$*A4!88w@K&Zy-j zux`jWscrN%l^v!&(Wi2hPg;6=rmDV>mH#xo(0uY5-6^#| zc!C(Z1Agz5Y!C~a4s7l zKb_S#L%gXQ*${G1W0%39*9ZoJGtBzQ3HcY87n`fin@!IA))*G07#4+pD8h{5sE1+E zjkfg^8pjyucGz>`4t?j>VOiNoEE|DlITGaoe$g?=0n+41K4zUXx}FEMVu~GRuiVHt zD!ai?vJ}?{vUTN1Im9Dc3{#>7bl@9Y$U(SJ$SC0`-7V1!3q0qJr3U9Y%rWEz`r>!| zW-+`0rUf9*WdYZiP*4PaE}WkIpP@UKUemjE!<-E@kKTme9^5r+%`JP7bjgi}UKm8( z=K34<-GA4PSyRIJZ@_+M^va` zNeoRBv!Q9RY4$wpEPDxio_L;gp>>{piF9enwbI&>H>B6Ye$gg#SnWW7FuQ_~xdf3? z^aFBQ?HYy?OQ6>X7wsn=(>qB-d>6B`YJ~n&73oh^k^WSzG^zfWh%o`G;MxxEBAnaY zI0`UoVo%aDx}*nx!%0BRC+TsLD3jHuL>5FYj;xMw5!2lPMuWnt-Vq6tLq)>moFo0X zvZuZfIyt_wSlM|4juue5O+JwY(HI14Ck$6Xo(65Se#&1p_z7hq0i*$`W+7lf$V@b!<+26xc zpIY2Ic=@Yq{yV?_p6fr^`rhD#SvQ@w;=%i`T=jGAO#Q;fw#I+^>$~SJ%>VuO>j!>> zW}+XWN1xrY_t<;6pLh1(d&lFC!z`Tx{xZxz0%Lyz%}(h1G{nI_EO9b86#`6+7;&5=9Cqi1{J_ld#uMx{UtG@}*}CEO zyp=!N|ISwQ8G8P1hGotKtBHZtM3@Su5kEI`5Y!wX1=KtD91te3uHy}j6i$+49omFym(M+{Mu3k~NYMkYFl z4;r9pPbWItMNdTVPDF4{WIxS&7@nJTf1hjv;aIkuY$QKRz8Rv}AEH+}e0|=J!Ed24 z?g@B*FJkp=|KeL(%Rk(V3MRm@fBhukGnm$E{=R9h9ffmx3>aBHQjl{M;G z?Z(J&{m%s~l}Sb!6@F>+XjC+qBkVd^WYx=fTFG7L( zl}6SE6fh8Dm`m_PjX+xf${d~fZN3$DHX{KeNznz8ZBtG8^uX7wX%qV|pp zH~;a2&FBB5cGSM>o*Dw0zvt#>(ODO)`SF5t*R44=)V6Wf!`;{Xd<)~|`-o*FnL0dg zIH#~nDFg3bn5rdl^3*RxNus2GhUjI~PZiTo^CkYMe^k9vlO!4LSvsrhL8cuc z8U$*lUzm*u)hH*yHyQ1H^|>aBxJ`7xL1&2(nZ$p+_v=EQq39%r=~A|i@+CjD#c%l4 zk-znopBhvAL)nuj#ZL`qE6xtjsW_iq8eSG(T(K&CRdPf8hU8u0N8?Y$KMNm!un*gT z6T?N0Euo)uJiR#4?xLDfos!3z9YKlX2|A7KUH0$mGm^}j&5 zhF##3Of_(;ilGmCQnp}w`G+oll4gc_*Gp}kNkH$Z_tnU~SpSyYB%2j{6{}+G6FFkb04|Y8I z!>jH?XPT=nI(7A1%hhPd5+uF#0W$B(|4;t&{Kxs8Up~XO{IqZ1-5bDv{egZz!7yko zm!@?}r>tYgJ^96{r4SK(S(IivR*>bQ?R=5Ud2&(U zDR6}dR8^mLzjDM;8`w>MP?V?L?;i3tV%6J-hBpd6FK!KcNmehUQM~Zk=ksD@Pmp!* zG`uaMvt?HY(hZY_jGyC6UY?a1N&Pg75yrcb0;s5DE!AcgiR>Be+$-D%9J`T2 zTt7ltrCr@4exR}&Riu*lrXju};?-ieh{fBCH{NtqBnB_|7X>wm$IO8NQ2N&Rz?A*1 zq+B&XiZ1mKw5%I{9i?lh5DOu)xo@AoZ{IrJSp!R&xlK89=CFD}f@Nz-J%;0^S9DaIU$IhNBMaY;U&=3+S1Lc|f2;`AVVR9q*CoTHGBAfviuC=H z;|nF(XooBZtYlqXZ7ow$nuG}|OD6q{6ov2R3*U_vVQCcbQl;PZbwtyGN{E}#KXf2l zMcjm75f>qU2t*MCiJYlGRZj>KwG_^(8gbl_QHpn5v!g1lmXPDBK5{gbD6>kArN&3W zIUX0G_`ColY149p?baF&Q_n>Ox6W{+mujse2u|g}N2?9F`pNU7g-SxMb&w=lPNVPJ zoNS--XE?D8FPPs}6IeI#png*7M>O$As}6}BvQ-CvhN(~L`X;( z(w{2I+v&IhrJ9_)ak?S}pG_d}P2^2Dz2&8q=P$nY<~iNZZphz;PPlsFDKn>Eb8r3~ zwCua-6X#7j>-G)#t^DrJCl-D8;pXb6x)*O>IF>!bA3ncr#>KTqH;d}TCDYHig5;6U zANrVozl?v4DMe#wh4@^2VJSuqL8oK$Np=B|Y^F&&ms!qSQrgX|Dc#82#XrVAq&>m* zYR_x0GW$!vDD~@BslT+8trKeebtQJ$$y!HnPN*Yx0l%d5O6vyeF7{6Su97Y2LA=HP z2R*<9nYbA=;~Xii?x@L7s$$n+lA~}EuqYyM73GyMCst*16BiNF#EIfi&?0V>>)m@o{#PG= z4dmba>Er0cz3-w?lb>ncd)uS`Gk@8EwGaFW|Dbw}1Fj!{%G>&;Rc& zPv$>e{}l0>_ks_b2X=43yf|Ldvdhqkl4G5IGifkVWP}xstd)9JR7M6yMrE`pAXAf& zeYAEQrCX>`Q4bL>D>c1gHGOVo&2%V#4j7gBt&QsMo>6`28CCLYjLLnR8(~Rf8&A9< zJDyF5k|6OCCvie78joT@@c{<-SRoV+h67<%NU)Ichi;Lp`4 zm)OpjUvFxzl|{mluoVhou(7IClUtmr2Ftn^{o}EDKkB?>c9gk)<)N`B zwf$u2Xv~~R0lRka;z~AeVq;KGUP#n_dt1tsjXO6%p zB}o(+mLpTz#hzmOYz_P38Ykm|kN5K61u&EU1u&E4Z$LG5^4YEx zxKq&P0b8!^(Ej6)jPQS6qNv4x^N5kXq2!K3EoV4GDfe|hS9$DSw*J^3*fsp_t@$ax z$ZK24*g&AeT?=C)Gq2IHDW_v|vxo}A14DDSjcol1)~uT|&~dhPK< zFcHEFtI>C*0J7N1N+xARa21op6aYiyY!MP7Nu7n@Uq&chT~#^4(kqKBy|Q5GT1TbL zvM`3#3uzr;KOGrL3f+RjAE~BLQmB((!7I9}QFW;|*rncJmli;^G;RBkuK=n(8ff}r z>2uE>0jh0g?yx(OCLKzDLU{_g7#L1??-ax`Br63rK8>qLl*CJ7C9I&P&8kqkEG<=W z>58hTR+?hMMj!<{2LrYU@5=eA6e>}`*n@spB;{0!sbpb6ZwdgTC#`k`B1X)g$t8BN z*~-e4P7_}{mm;K-96-~qrGjh)0(yi(y3UTMtodml0KxTfRsIow$R3V}qcK1`X|7(?Ao#flv#_ zCS~7d->W|C<1to$BtXRxsvs4qg5;^f&JM{IMS)bEC>aA4$SRbO(Tue~^2#Af$`B=G zxo!<2g@$^7(^k7$qV!Qntd$K+_sc&I?l52cLz98&Ek*y(HYu6TP%QbFtXS6=o zRcPEO_y$Lv>RTOcqAgUJ+!*R05KwK_2eX>hma;5^fNo2FJf;RYWteM|G6HFitAOQ$ zd-0LIdj|!6_u#{L-jV6JXRr;f<{1E{t6|Jp)J`i-*t>q#6R_wG1Pj7c%?;!JQ5bN> zlVMk0bsQ!OLSfgV&V0~aUAeD=U>zpyEIkuXplvNZ%`MKlq0w2_)H>^mDra4qbk@OB%8~LdE4G6_>l1KB`(U}1m@pfp4KA{-z4 znWxY1y3S;#)#nY@fSKz$T!;=J0Ch4u1NAUcfJi%G6lH^>z7(#Jj#d50QvUdHFmSXm zk)Hg2xVZe>85h>;>sVfpC60$|K`H?iBE;dkUxW920n|9YmzOW zkdfp`)xL4Uc;CssIqX{YO;)_j_cr@BP$z==l=9W^8@ToS&$-Ve-p8SF+#4L}Z2mAS zTd5Y-CJUhBJ!-}xTYKQWs_Fzuj>S&k>Y~x_K-eeB zK3VedEXUcrFUa%o4iHHQ0x0=>439YkrUiEEW3hr5t{+dz8jU>K%x~lO@E`IVe~Lu5 zDUBksA>`jCvSL48+w+YG1+Gc4|J9K1^I>wdg`^YehxzDWu4{l~pon8>CGgYQN?w3} zEhMKvI)`8#rG<7;GFzoqG;>?@%$eH~!x;n;q`x(>)5+zMHwSxEKN;GC*$4=Nsry?b zQ#V^=BKb@(Y4;wt&iY})BE@;XTn=MADwg5Mt2~hbqkg|H3}QGVkSS2Cj8q=XaM@sn zOv%nF5JQ=w+(aiiGU{59t7k|OBLRnh6adF&2+;IlmE=pt7~yV4(Y`m_-S&&4y6P4YSTk)0wgpepN4 z9$Vma?6>B)hmVUbgs+P&4&)q4OXwTJdi2#XInO(U;HrKP81)5ZsCO`oV89iBn5^Rs zq&md`bPU3X-U5IY$H_^$=BIQDkQ4--bo|v2NwvtwyrHr(gRmqkIwQ&0rw9~-Oc#KT z^icpZ8PX==Uip{al^^RJ(ZNe9TT}MzF<*Uk4{0i@cU6S(I(o}Q3f=-;vUJJOB~O{Gx=>bgnhX`$6^VQV+u0`6n%4&Ijf z(b%1;?DLYgZe}(sclhkAx>`ZXZn$h6DX=f@hn0btslK9e0z-X~N{AF=8_P{(_T!FS zHouVX=D|bbEj@n1gJPtA(LUE29i+a4-F~6h`%)QwREqWt^-aj= zO%tfNvjMiceL?k|E4p%kCZrg_konRGp7Z1}0@!d9pX9H@1|ULzkBpyyQb5O01@hm4 zD$&`E;n+B|0P#=eJ08!^<#!+b{FZ-j|0#Ry$aL?-a z#Jl9>G| zPjP}s`#t`3MrRVp;Y2gz1`3+NU?P%8aGc2nm57qy9*y+r&*^L=5=~&cH0z%gm=(#! z=kjyqIp%DC|AN50$bx7`d`{wq$eq}XC0W)=DspH9*9;XYNyy`xeI22+Eh6#hqMH#! z&_y!6qDQzz(q=#=RU~YZ%&X`Xc11Gb6qLnycPT10JeO&BDr6KQb0bYOr*NNw8=?m~ z7@-JvVaJr(LITu}r#=nH7Kh~S?d*+q=?kz8%(l_5hi7P(6<#+iv@o&&FbkE-WL+^f& z-@Nk$H1FyB-}A4a7L@2g%5C|NoQx+o2)3>7u3H{zN%;#z^E zX#Z;B>G(8UteC3|R~NdRDRHO6%fr!Nm!vYb>ncq^={iY3MZZ1))f7o$n3q(_4{{-y ziED3dTY78fU-K{KuR~Wpb#Ly}v1{_z^SgC_Yf;~_C-Z}YzhKdZ)$@NG(n!vE?$AyA zU%`GtObuq~4BWmT{j)TVMJI%?Qo@yyq)o6aSRvH$4UzivWWF^rDSaw`YGg(_$Iq^q zo4%O8l3m4bU^no$Gk38MGLNx;VEz#Pi1{e;Q2uT zs={^Yf0l42JtI1!C_hogb~w+ zf34$PoA(m{n2@gK{@=P4nS1Yf;MdRRpL%>7I_X7%0~ZY**s|;~F#osne?p0OFPMM! zqI+`n>oQlKy$8+z@$`5CCf@y$Uo4p zFs}7oXZ%Ea)aW-p(LXj!z;fGf1pR))Z>X}Bz^QoHCs^d(9X=|{;Yd7|j66NGf2XK! zv&YHIMIub9oZ?&*G*Oq5BlLD;`&S_)l1%G&3*Nnff`?2r-4~;YKY>-8$YUG&?+o$!s^q=E$2$LHBy4;0%Ub!$I_$hxQpu{XTQjG=exI5+C>h5IIp z{t&`ITi1P3*2oyI@PzcmTe>toUOe7x5_<^ff@Y1s-852Tev%Cym1@h6E*dfPA zDmbewjl~#b0P8^I)G%Cpb@GW{Da}U0kw67I8Uw;sP_(7ZVX6D@`hCA$^_$n)YG$80 zbZGDFi{><>X8t$2@7hhL{p5jsBfopr3s>CzMrl>$X_w}^(AYH_CMx3Kf2C~mgey+I zfZUTef9PZG&-`mlBRiG$toWJgqCTW_kzDBHh50hw8H{;C9E7Q5bU&@A)~^=HN|9Vr zBqux>V)Ll05ZDutBV=nj&SlT#R0q~mhB7Nr@cHg0iEW7EtcfF7;kip2E^oTv(G4aw>%RKk<*-fQlZl3Sme|nEz&!@S zOampA38)`!%c>1YI}rHJZ1TfAF=>swBc}paaEd&lJ#=Ksw9pTw>+>-vN-LTQUcKIB`LhX7Wg`^P$q07Y!9TNKK* z?Wf65x7zM`GFoycw-%a%x%&NNafpl*7&)Q$q+_C!q)EGmZ5$Q9p%$Omg%YSC5pLjV zN~b{yCn*~WvtC6K%++ajOXB7xx2RiLP1`)_JyC9rJ`{|Ef4K;?XX4({^LJ?rUbyPw zpP$)2e{z25>EB=cqtE~2fq$&!cN<$D-F9DQB6@pn_o}r=?|DA|#hvI)^P(H)d}rmf zlNMJ*&Z(d9z@m$vJ@5O!y;{HFrmN4M)!e+KX7bLd>jlgPmlU_6wp%JX$ zL9XZtf>&h_fB$KfLGY>!;yfkDN_}@0r{2iZJIulTxdSGBR=^auTvPay=w&2< zKFR=s3W~2yQ{3Bx=rarg`BH9uKEZ2Sw;uU|jNN?@f6tMsSP)Hio=1^3=5lkT7bPy- z@7Bj!xXIFV?iA@V<6-_2LsS{;C%3!`a&Uyh3>FzgaJV!OOk*#i$AyRvE(K^_U|CnHdoh7uRV%FSs0Ue=xCLumgGMvx3)?Jh`{S7u2+;-Qync zHlj+mX9atLFYaZF$Zl>oC#v+Sdmt1gcC!|#@6*WA$MCYmBg~I^?`8A7m;KGnjFW{R z?aGy7cvQ#KuvNY>YNNVPyXtT2@E)P8hO;%91sL6oe}*w8 zTl_ZP&f`XYA-|E|!yn{%z8_!Lqb%Iwq!PQxJ@MofHJztW#A5?d=SdW9Pb6uHbW(-E z;dI~*#sDS!+YZ@6WF-Yje%tG^pSi6DfA$`K`aJsV9P+;@(8K|`CFl721Sw$m@r)#S zi5wDBq)@Yy3~WYt>fj5%M^}w5D{nv>o*UfD?>_ow_wpb7fUBi-LkI!H%Lx0&e|PRO zH9XydxdRJyRYWh+GGl14um?M04^Q8W;VxWGDAXZ}6wgs;&l|Fy0Kez4Djg2tf9a%A zq@PBS16GG#ho8~h7GYP;Hh0uAX@9Mij%Jwg;H$<*XD}!GXILjk=Q4BrbFDd1^A70_ z1N)<-jAqiM%T$_86pz)1TKE=q8b3{)89IwUOFcVu9)F&?Bye)tm%fK1_PEw{wt{{#MP}mJQKCaTDAOSot+nw zWSim1vzh>h5fkMlDH)0eL!qdp%5pMffoS~<%&@}y)tV+=kZ}?3BV>l(Ajhcob z%b*5uPEpJ9`xz-7iNwvRGCG~HVZ=^nLh#BmJUYG4CY^qo_5lrX$J}sgO>y+!GimYC9lP|tvDq8=ld(4%JgEP2KUqUD+uIi`^AEb@t2O|<|EV9F2_sOZeZWQZ8DLofb}o%H6viwnR~Vk$+u<*C zuj|8hV-+?^!_Du!P%s_uQ*Ah!2t>V&@^K+XwypyRW({>_lmzJW-pZ zkFzEOd{%(eq%E@0-9ohHu8RxQ*`=gHZF@EB%hBZuPII+ljZ&wlt?}F>X_7*Y`0vtL zTuz#=%+t@Z7NbSnh0+q``}!j5Qf`$*!iLMO%L8k<_2PQp?OeaK%X*G`QF@bmOL|*> z!}^%}MEXQOV2u*!e*;WZKk)Q0St=4)0$_gGLj>1m6_p7E&8W{WkQn@vtWG3TV6X-* z24k9)C;AF%;h1L*EK`;d`Cq+Q;9~(p*ED3Bn%@cp6qq)wDXbdsDM&DJK=uU!HY0+47TI~TZ~q(AEu zdb4J``HIP!uv6A&GqGT3Z;E)5`qK^(`^!Z?iVfrjav)F>%#EQZ~MWhI#ae?<5!yfi%=X$@H6$O)1R63c<4kh;WZ3yx`J6ty&U0%A&2t%{FGm`G|M z0^0%+*hVA_(nu>UHrr0r_0_;6u}hOkG#@v|dEk>oH}GrR^2FL+V^N$|3( zLy{-4++>)yk9({LvDuHaItW}07A#rFB;OXL=KNN6G6-A^EG)2Msm?b>=Pp1O2p1^t z3mmZze?b!ekFhU-kE%TPKJVH0W%ezZNivg!OeC002*GF$DvKbyOht*JA_}4sM8t|3 zt_oVMQhTl1<$}w_y(|ffpf&eaz1M{cwrYRUtI~=VtyI2#lv{x$_kEvp&ddqe@AmmV0CxFN$rprYLHLVrEUJAA-fP%_dA;AukDLD-a;5Zcy|` zH%y{q+cn)?FyNe%Sm>}h;M{#dVxbN!L%ADUsF^LUE;OKTU z!6usR_-Hh2EWKoe^U)k1GO4pE5sbc4(lE>O{prdo( zbyqXyUtsa|Lx`1RR+Q!1imF1rjK0O8RtB-yEn($)B~?J=hM=bx-?IcoLGmnq30Eob zv?5nxoha`{gfouCmo`ZWqeL4!*pt;x1t|#~Q5-*$ifbgU#jeNHqgc6-uHcTTe@DAJ z%!B61QloT-)eh$uh~2u0*3(VbdssFX=B}Z4N205%+EJ{EsH;!5#oOs>xJY@>fB14x zGPI{+ADQPMF6Q01INuDcbZB%N367Ca6&^u^W3D)y7mqtlTJRe^NtSOEiqo8XDTQ(c!k_*oF%ly0or_#oD5V`J;ZI ztr_vt$j=hbY2kXW39b(KULVrA_4+3L8=cX2dunG#QCD3i$FDqY$D?+L@M`HW`>OL~Hde27 zb)p^vjkm3+>nSF>lYYK8=7g&xqunUW=gx^e5=x~6s`P)M#@ETsDMlG_g?R-v&K%aa z@pqr5Jn0q@l_JH%^3PRee@XJdO>uthBoDGI(Fj@6eNE=ov!v!g&S#c%3@YSnXWu{0FB4Tpo##K_&iiOc^xVW&=$_0Ii}pmOGwz9tY1EF;spY{d525645)nOKmVNM zFAnBA595ai9R{+}i@Tkis>h;4LH-~3MX2uN4vNX=RaGCclR1MFMpJb%(+o1B#G=tu z$YD+rO8woPFk%Ize=Snjf)-1X6KsROt%W*=WaJzgl7x|PI24K2)H1xF)6P&VK8Wd9 z@bcnKuS~pYQtNg5uR$&2@4fTZip{Yb_T6{y^D|5-TK!5Ydgbdk&TGDY(X~(3R@^mb z!VC9ITRknLYl&=5zTu3s=XS@s@1J5{F?r<5BPZ@Tdkp%xe?Dc_Pi>ks|I+Da-$K^$ z8oZ84zl%v#&;eM-w;@h7vRo@Sp5r>xo6~eUU7c!4ots*kUYF*_20J1hi3=kaCc4Bf z?P8-Va#>=rxJ0|wxFK>wqCfqSx<9%<{>R|g(XZp5RUAkUrQ;c{$!H3V;yMkRyU>`y zE#&rB{Ea99%FRM#<~sE?cAjA#0mZMkw& zw>|jRe^+0*jxNmk(TW%U_2v~Xa=Qlp_R#c)-o9z@o52r%fqwGZocs5@v+vD4*b2@V zI>a2tb|XPw;n?r!&=Jogl)bTM$rB7uFg<}>B7Y98pxN!U@z+{MZJ-WNM{pQy7z$PXjw$@rfk?ERPV!)G6pgGdg1xCuQqbRb)Mp$1QaX&v ze=7Mj_81XDww`wiXSR!HWV>e#jdrwf20sNjvjJq209pxv)&;4sr@X@+w8O6Qt}2GJ zdj*shIt5zLp@T>!ZyF3=oThhybWwMJUaP`KBd-ai;*Brlmp* z0Wj0CrQ(}k?jQW0WnbR+(toEn#qYf2-shjbd+~$lp6HIfr~=6^B6{_vCz97K`Sou< z{P%ytnsNe0?x)UNG#vy@xk{#4EvFT<^EIwD)SCJpeUUsXG&^+-y@0z~x+*k3f7PFU zpZg&Aas2b(=b>++e~y0+8ZnYi=MzMYPDv1*DvYGF+Q`UQx>cJ(kJl!IE=YY(E^60k zpYwl;97jiW6NMRFF%7IK6~Usgs>C*DoIFfbmbe3AEr{A(_KB&SWen4*#&^OkTQqW} zxz9qTWn1&D9t-PLvQ!-HY6Xb;f3m=XA$r#0$-=Tg+geb@AegXpf(gs(&9%H9Tx+-Y z?XY599uP|uY98O3gRP1O4!jsOx1lE@w2i?L3`6(+((r=pF!Vo2ie*+i>s}!A* z6-QGlg5hY&&XzzsR6VL%iHXNH-a#8_X7`i2jJf*tJ3qL2@%wkp|4CEtK<34pSN!X< zx2=3)&A&Ww;;HqB`N7O_w0?X79eDTce|vNPyRQ@5JO$h4N~|lx7;zCmTr^Fk!Z^z8 z;<}_c%GJzu+>O%JiWqiSf5+jRAGBu?sUii;UV)Fe(&K6G<8C%nc@Onrt#93)C+9d9qeLE7otr zr8cq7c_fJS7#Ryb^8cn#?kz@b4ZEaJjnX`NLd~0Rfvk#D*HGB3e<3ZACi5P-+5)-X zLEO$XN=J5k4)OM4q@`pJ$^*orXQ$1qU}qZ&9$q|{xoXPJ7fI`S2|_7=kfYR603H|{ zBM=&HYP<5#OmYxEhv9S#5;9&%jEpI{Y$_cC-5oB2h&zxElMqR}f&vrOgRKEK$`$&l zeI(n$nh}CAZHY;lf1^w~$e1!4bk&=j1ob8h-Z1#(mvuGet(K;)Zl8*C`XWO@6%^Z0 z6;O}y%w@Y8|MK#egWsUge}8~(b*PheFgjTO@ zj`zpeIHblB=|Y95F{+W0QJBt$f-J*R^7;@84F#QxwWAoc+44ZWrx2p<U__ntYX0L{z!RJyQ^LUEg@pt!AJ73Ahg>LEu`O_UPV=w?d(>NX37+-9M#z^{VQ z2Vi{OIdmKdf9R;EV)0kdE~<(;hGfc1r7+bw6XG-O)5 zB=91RYD_7Rq%7V@qCCnstX_@sScNQ0ZlmN#kd&d%=v%_@vH|@*GIAT?nw^gIn%0)q zLL2EBz=n$0sW73j+`4{!Fmcz43+E-rG|xJJ?_TDoe-CtDSD5gD-%LR;bP@l<+%K} zus*V;vF@CjbLuXvTi3XuQ5an{dPHaA1Z6_i_z@RXT{L2ma8=b+Bjz{uH14lERP~pd zZ|baQe}oV3q__0dr-A}_I%b9%1%6Hs02+t7^zF9ErBa4GzB;AKk#I|{h43!>xt9Ox zBggRw!m>p<7mMwSA~R}7=SO>@Y$Lvk^qfYpLQ$|n(UKL4f)ygHfAH*Ajuj$D5f(t# z3PqjC7A#yn2vos zPpufPr5af@K&==F0z0D`DCSb+8#z3l23RH|o^M=UMT}E^T3NGnyZtJr-#&qX0*!Nw zFk~Kd8Ji9|<@avv7-4S+FVYA@QNa`ko;*I|YBlir;#K*}_dq^Lfi}zc;3%6`Oy5nR%v|$=OWHQyk2*en450@e>p8jj?|WCiz%;zq|Ju91e)HEvpRA=Q z<`DE(yyZ+CNAUU%N6D1h0UILw9NWr_e`j`SEIbvC#tTu=QmqifA<9T`LP(L-Vg8Kj zLzU|JHg;W6%}I94=)#bM`Xv+rXC`6;8AUzZh6s2hl18zBmI8u1DM5~tAnyu055ZB9M)W;`j&8niOC5P zz0q5T{n@Iq04{vkTHAL=|B7Euf9bpVx*0$0z~SIuAMSek=L471PprLd_Jg+%?8aK_ zUJQs1G7U`$wCv17%cs`I%e+-s7#DYw{U?11v$D+jWY&}WinQXz>7KxQf`En6n-2J* ztFp}bWY$;fXWgsIcmnSU0v3GVv|J-8%bZVUOKHBgqBNRZ=jqZqX@j&`f9jV$m5xXP zC8edMQjfIWed>TTB*|$B2YdocGZN429_n}Bp`pm!fheBiS(z7d9L26@H?W)8e)a&% z_p?V>nqo8TKKzJfoje0Qhb=*k1*owy`3fu;P1ZA-tk;9ZlB|SGV8>1qPX*jE*oBC| zD(~NbsB4+ObT#}>atAAOe>@>rgKbfq{ci}v8iv%peSLlGpZD%P5oT*o?5F6VCkJPu zv4EEVTI1lQG}q|~YN7Bkg|+**awP6u^rHIvb;_~e`%#tnXWKoGShA& z*T9|BgtU+XNl&E`@>eRk42lSuE3hU?JQ#YZYT~JOgk*v`rkSK*+D&y%C5fLrP+*j< zh}F`v))XDu8(lPwTG5n~NYaHQ<*fKq+MbhJECH{2TUufnivLpO-D`y$9(dB|MOc#8 z^bKBHJv!Ysy02y2f1?+$U%vO=x3@j6U+^$H@5F}Jr!K(i4zGLW?_`Rc2{;pWdZ`X5 zeOI3rERs?@TXN@1B=0WmyPYcXP6)^s`Aa0m(EcxXjAtZ|C(P-@mpwu91Twp4Lnr?n z<`$U_@R=YK1dsFv>PUg`NFTlraPR~)035OJ#?SC9%dvc$e>4%pfj>jOSiXh1S>Dfl z#tR#HRKwQ_IkBA|BXw%iwYltE{$gRSbUS-1_qg;X{~Pv0{viLQ@IU;wVmKhn9K*0Q z8DW=1{6G@LoHMx2ux!p5W|#3YXGvEV%aK+ZMWJMNCo*h_W1%ckEs{s!4CH4_XPj#t z4y4Lc>mH01f7K=MQ*u;k`IKN!m$;Yc975RF?xdz;O-+aj&IEG=_@o^22GA5FO^VGA zlW>_DH2LccQdpU)5ri}SNB|pcHWky#)@`Htf=T9e>3V^E6Aw&`&%<`x24J@mxl?` zZptnF^F#ext6UTiu1qz4poA z6L)gEe@?!FHV>{CSU{)0KS*}Ax(nOSHeeH3eY*856~@2AR-R%LONV}k1w6&l`QG(3 zySAgqf%yX7khU=ne@LO#xgT|=bMI_@*Kg;r&u4IHZaw!Y$4rv zoWtCSx_VnFpOgd_J_)(=B+;r6R3ugM znMtoco5UZrouXT6ybr1I)N_rio4Z%+$<&~ae}PL^ zL&4gRY9&!X3wr^Emm&LyE}|`)assPL#4BO!h-_b?2ol3rVsYyd-U)1*$=sB;4#O~Z z5e1HI2uL8A;tx%pXx_MZ#iQvv-u{>8du!&Mv-F?)E?#iq>alF?BhxOw^5R{awhz?N zzgTkl*hiioc$D6{a^;Ml{%GJMe=mCd0=$RuesD?u#9W4aL}u7}7(L0FGV}AJJq@SM^~btnOR+dMSiW74>WkBGwp0uL{Ji z3dF5SDQ;Cj-zn8_1Qa#FVT8C9KmOJ&a>{P?^O!R@sz7M0ApB3679;vKe?el{*pV2$ zG`1nOIo2OzV+`FAj(FIMcxa4xepduE^szq6atTwuGjx?t30*B;=*qhKxZe((8VXN~ z0$p|Kj}y!ug>ZJ*FY+Gu5pWK49xlhT5#EwyQ5Ix|H)}0kPa;DOxUeIXZQaCqNZOJn zM=-b;E&!0?yj)2MPHuhPe}|>DPu~3T{3m9Za$m!BlWuy3t$lRU_@z^uZy&gcUUS3s z;~su@;1z77&L29&)?u`0R2&TvylfB0-0|H*pi{_B1oqWLio-7gf*e;T@{`0OKUchl zUnGhJb8KL2q%}6)oD!H486TU+&68%CU4gF1tl0J3_0j_K`oQ&(e+98yP*~zQ?Na6< z?jre8bqRAdceT7km7^(Eu&{;<4a>cSd=;QjDfea;L)j$c*^&S^p|oY50CgU>bn2DV zL2xMqoJ|Z|ngI~{Z9SVSj1mwfm_kNigi<>RDGq*$H6=_Okkmewbq{2vU`=-mkK^zf zpj4e?cY)uRf+{YRe*#cJ&fZmCpu8zy)1qwr(L^iKlvkK6Z?mYnr6%gk1WE6^yDR#U zWOnDfuzT7y9A6%10VxSVo7HS?wsa+TrNk094;0lF#d0b`3LAB{RTO+Q25rtpGLWtJ zr`FDY`o1@Qk0Q7I`TkD_55K&1?V7E<_pIGY2T|RFD+d2Cf3WAz|AZ=$_U=3HzW2sE zZ{z>c+QCI^6-HHnsze`v7Fw>FXP9T3Q%trqvpGYjGb7ZRiso>0#kmzrGwU+q*yz~g zt^I=gOZee+Es((wRt#v}y2>l&(;Ed>EkOK0w7wfJznP*?lrHWm}#v_sDDpV3o1m zailMt&PF-rjVF2WS&8DuY1xp;DluSGX*mkE&@JTxqNkGFN}?Sv267bj-5nTSK%^T9iB{|=*O(%>TI07i{TrO>YcHA@saPdCKQ zqNmWef2w?ExHCQ_zOHgZC07U*lAV?32hUH=4$e+q6}&1rzp|(Deg1>M7yOs%S21%0 zU9INB?R2Yp0X;#zgkD5{r2ankS>((37s->ffmkh+NGXEOhf*wtN>p#5hM|QT*2qv! z{Zpg>Z6MRIjrm58!B#@*zY_3bKVOhz$WeSViYGB?0hIhQk9{Zd1c(H(fuh%G}uS=$uyvzq#?Zcf8U4_T=q%S)ChiINtyB#mN3q<}J@WT}3gh{Wnl5C!S#Q}?^|pY4B~^Daej zf4424Z<_YnT?8`1*IHf4vWyT}PJ@VqJ2M+r6FYDD$ngI`CC>Ekj+& z9mJ``zNE5~8SV2W{eGlViW9KSzvszw7Ij{F**WK)d)8&4O1Aci?nz^xshik2f7!tM z3 zPUNa0TOFz%D@~Tp&lan%u3jZQDBYdi7<{4e-x*DcCSuW1QyM>va!Gm)O`FX~j?EM2 zN%Q1+$~<+Rwpd&&EtVH6i`B(iUu|EVK}MUiBSvR0k>@H4Y8TWmuUVe$$^KaWx%zPZ zqm7S@dRl%?eX8#1`rg_%Y9sYte=t|=2{oRO^@MsS4d)(1gc?uCdO`)6rU+EFUn17! zRGCd=YQwBDvLZoBkJa%;Xj6%I#;3>$A+ zn;NO46DX05+re0&nY_FiiqkRYmZ*t1?2jGKkXObt>KaWI zN61N3Unj|Yo=s9|vw}ng4yQBRKrq^nU%h%Y<F(;72yAc%gw-KZ{Ab)P_3)28%ehoMz@{D6M+8`Y9%Pcc5XH9yKU9V*4&TZe0=)2 zF%3VOefz7ISewJ_1}9DYpd+gU+D(!aVm;#fDBb;SVl-0Hd0-d1)t3O zWSKAr*OJ_Lzn#TGPaIK5)nvp_5mU+=GWHr7#W1U>YNUOKfBWXr8&+fYO+`b3I9?h* zUsx*i2=SsPG;_Jlj>0++2y*~*c{-UIS8&K?9d%{%clp4u|7-&Fo?0XT3XDveAF<>EldRXjTnXSemC3F z5`;YtOP3|Ef88<<+ut=eH@Sg8F6uOik#-NO4R$Jp`FPq)T-b5tlE%C5?%lR6n6IyV zV!e6J)lbq_J%EHIgFk#=;Kx%N6U5Hkh3(7%wibWw9Zm&3K^mvR(E^R5j!3T z74kup6@w8K1tSVJ(-uDeR7+%7)*<5a$s)e2LnIfAf0Fb-0&)*g$T~y=&}vZ{I*5Xe zj+XKb(U9A8;nvBckkX2he1k?#`A`(~M^SWI0$3DCsv&VCK`%{gNNi3FCD=r%%vLJk zxy89&QpYbj4iciIjI>WWAhD9?I7lVO!7bs-P`HPQEGX7Pu0et_xil?4EYa)M!cR{s zI8Fp~e@=I_yE_|VHIraXT{AQ?&rEiUV0e>NlawY}PVuavVYM?{h+R1hehbo7j1u7i z2Ay6@wbLh9R|_?>XqkqY>0I@}Wlv2vl|IF~Vdl&S&+7Ym-=yoOx86iQJka~YGbhfR z{m{L1`-%M+1qsqefl(mSSDiKm|yEO%lPMhbtIb(9k+S>zF4 zA}YuNDP>dM&sP9+1v^?fL{(euGO^m4)hse(vuXl$x_@jY_yWs>8SDys@qJ-&fB zPpZxps0hBnkM`Sl)Q>Ds8GK`?BdB_*R&J+S5O6eAPEm}*jVeS*|6@MW8f_hB)k^Ca{r2HziL)ap}MZF>Kr#_IsraqHTP)FrP z{NIsdR79?)YUMV0I%UfeX9pq$4#T+MR-7cl(!djEm%!ZsstgM39XS`k#RjQsd{*FD zn&VW3jFx5?% zky|I zD;ef<$6CsN{B#P0K>@C{pFshp!h>0uMXzYvHaIB58lAm4%~gsjTfz;fA0lU zlDW|x7?lC;>sK(cN{A%coL~7GbTqft=x+GpRhYO^F9lt~Co`zOmmb)7gvz}lPf5RrFs|seS z!YRw!JJQ(#%d1k5PfGCs$5Je>NQy27Oe)BPgp`<6D)cOs6B@+4UZ7fqvEo_!`OHM# z7N&|*l=F;<*5tsY#;m|~!UFM{z^(lEh2`SQ{4QgA;BWj1sa~<_sd}wWuQ%!fO`$PV zTi_OPjrbVzsQL_gmVQ>*f2eMww)4C6|71VpKaviyhm1c3j`GK)lmeu8D%_g9GcxG7 z$B^Z9)k;#<4K_eoq9Eo3Bd3$pl`b$EQghnQp%3jgV#YMA9U34%rJ+!emldm4&RZ9; zv*dZ!5^I(91537K7V8RfIh+e~DhEeX{%Dg!d}SUae;wBu|4Z5-e+IZY1WuA=QBhUd zv@GmFOzGvQ01gB$uoudPp82&Uh#A2O1oE5^;y6La*Ey%@Ax+ao%P{h?7{V_ngdMIX zqi7@qSkbUlU4yR|z&-%kmx!pgfI%2l<Di?LX)U8>=vRgg;DGV~UjO_0s8L2H;B6WW6Vp>R7iO3F zI>e!UTZB;vp0AocWpj(4%tIVHutmr?zYGlD6p+vg?%R$-e=hui*wXCVDvTl@vy~b{ z?{YrA^ogaHNBu9ih7R<~88$s!y>zG<*;_j4nDht0*$4q9*1Hw--X&K`Q< ziT(7dZ725=Zumcyj;jz6Q7HLHjef45?-$-NB*TuhCzzlV))Hnb8mp{E z4=Q3);Ct*`VXktq{wR7(eoWax?^OR&d0T(i+|PUYWSQnqXW&@K^Nhp6!AroxVHhSM;V=x%EHQAHGH=j^Y`#goDbZ%G#KG~VhP0fY zhJ!bOhC`knK!FRiJJf2~xPq7Nux0Er?6CP6d=G4kd7iCjm^G;%NV6B1_TGvs> zi@;8VfBCt2^zdnn8zb{w?lS4R-E=573}Y>@Y`pH=;yVGDH#%IX_35#Sb|Ax0D%#cR zXgh;{$m6Y5?Iuu`h1*eeRl8)TO1nqQg~A-P&ww{#t8n^=bA&JMaC&ZpTB5`;X(Jso zOdT@N-Gh(+;i-|S#$50327iR^|9Jn{!7u50e>C{*#8KzAoETIG{tHc>JJ>}qS2Z}3 z`3uHef_?)scKE7!9lNDDIIsBW2?p!YfCb7XTlaped4gIxzEsdUt=EtQINn>8V6C14 z>k2t!Fbb238v$P7gLc5kD7Kn$;T>D8|>qA9j zf0NAEnvF4(sUKDNU*5hwzNso}bgz9*l9Ttzvq_VtN%L-?X`8lbp|s)EmX^0rXrVl$ zt!)7-lmcx*1cdUGiin`7I6gqfL4hK*j-yCt@CEAUIDF0k`u#-5(W&E|%Q(&qIo!QZ z(!wzF{qFbAy=i(L$;ml;ulHJe@3nZkf03!=db8T1_bdG>zq&wGpw8DE)F}h{fT6-% zqpva4n40y?hGtWTbhWxe*JJ>(Ef1*_p z_2E@2j7p`#Ko|cjrSt~K&f9U={)Qdf`*7(gErCeP*oSAul%@KZ9xv3tp~w0@825@6 zGSEbuf_^2!Eap^YtEQ=#>8cxIVw!O$!&(9%T-s}Mt|O|1fG|!AyAtZBg%2$JwX0VC zYTb&#R0}^S9udkLyvYjOt<%&fe=j6c&Q!guAu`x%UNq)R4=t)YG>Et-;~|66SIknOmYRu+jVmRYr0g+hd;Xrm{_82yRa z{82G|Q_@~1CIRs_HyB5cD6UA+`6NnV`CFGm8R?-fdWB_UJ=yE3^Mt#ef9C@p+fr>B z8;Bol-?(lyUiy!>Um90)2j!9gk<7m)T%v*RL@t4Ut%nfPRO|cjI~>+SZX(ahg_xWi zK#4<~N%>Z+k{kqaKpy6cphz(Z%5WJsNj{CA53}$ru2w#sUj|F?60Sww1*^C&`A*ov zZI}NIu3?*%^Ffdc$&0vWf4Pewqf+BEZ_2|&dC6%yZnwS&@F=+ga|(qQFtI-{(6YgJ zu_Q$Lu2@W%l=^6L(VPlt6u1wxy~G-kNMFPA5JECKupo|TXQ&Tr0BK^HMVk9G-)kgd z;s+1?O0x@o^f$Eatx~ zEslRFt}9IXV!UP`Sx_YzQY1uiDhNJ~#-bC@<0vf2*;}V66e%bZ#phPkh?!WZ-EifE zR!sAe*nNH4RwU=lwlUN?K9N!+21XR-B5Wl8spgvkmd-*vsUU`YACrA*8TIufiDLDM zU=<~oS)#7Jl!EC zOm|ryll$Fy(zT7ve;wb6{J5SFr=5JlrWO+kapx(Ob@a*3M3R-ksr(O928oU%?_^z8 zF>Q`mfGJ*gm5*N)!#%SiQEw)s2Yq_4#)rKQpV_DIN`0x`NM?RIih9XLr!~4zI@n#1 zA}2>y89B-ef8?e^fv+$f8PvQB(ipNaDJ?E!lUQ80ct5wkHg2RfL}Nym(^=^8a9QDS zF5!3!C+86)N}JF^Ns+|T=15|7^DT7|XtMN_3>GJ91$y-PdDvq}8O}Lz`|4->!!Mxa z-E+dhfdS#*+wVckFP;=We&Gm=c=~A=@!a#mf6VG~f1KU<@}>G$*KB#&xyI2xt?l96 z_tb8ae0)}T_?Kse1Lw{`)7f9b(zENI7Cw6BY2lM2M0WqmL`<^bkz!~s#FVnCQFMzTWAkC2%APxW|5VuXS)FdfS;rm27k_Yz_di@~FJ zh}XJu1$n`W6}Dau$?g+N!oM$CA#@VFQ6`o7e+vqt>&~Qy=8Y)GXV@Pa%fh!4J7R-wgyQjsO zf3?UdPV2rpH1zt%UUec3@Ao&0mJN-+#>C+&lqO2Nr`bfrDH%U4ju(F=7LX8|rbxt$ zlJjAI)hjOCAZ_}ReE|j}JBD$u!N3qS5G1_Ee)<^OuJ&v zs}M%?LB&6avwDju^NU476R}+?5?>_`Nsq~8F=B-S$V9f&5mrm(2NT2YvV4N!hz_b6 zJ4+6Pm*LAebB43a*fJ)rqwTYj54Mr^+0jqL_SqO#Wx?$hT8ZL1!zv_@YPB#jf3?M` zPwmHxksZ=s(W(8V8qoCPKBT~lV@4g=?4x8s;~PjF)cBD#?fIr;UMNb7bSNTzjmoFE zE}5n#VQZbT=K@Y z3aPaJX3~Fa8fXt2f=)jd^nHe`!Bjs4k#)on5C#)ah+h-Iu#&=oK!f(^e>$D@rxU}g zY5<9w*D94fFOdXE-%qEdTCHYt+Au=-tGQxH?FgNjn#kR4zM0iTCUr;6w*w|o9-WF) z*IuJDG`hUHVvfqB;mk9tibofgrtAr>U)!^}e0ck0pO2vHjnFBeDJcNy*}yzX9~${pQP?&p|>zl->Ld_doazhyL2n-SQj$fAAX~ z{i&Z%{Dw!3sFt0_PDL_eIiwKV!H>cyib_#Anug|}h3GC~ZmmHZf6&{pB~8nw&zd!V z?%H*Q#rLcVj966fnOvdbCd638kw3fBQ#``s8Bxs4wdZ9UdER25TDf}V$~zm&#@*Xl zkb8HF-aNA!OGlMdlfR4wwT{%<&X(HRmQJQIL!rsc%JOA2qVSdTMd9-wo);79hr|4b z=lS!5)5y_zdU)%VS3Mo!=na!^fgf7V4d@Oo}IKVCtO9?s6r z!_MSIf{Yw|O@H=jUUps4m8X%)?W`6_LCr|jUKB&I zyuv&bGgfNw8MlAZgp7jpDP~3QsIyb+4F@$--7V~VD(i1~m%mPdEM&`~@ZhCE2oGMNOhBLH)a6ABB2Gq3111wk{po`t zGHKdl!g;cR$RT6K;>8)p#1_6iUcU_PBOBqqRndhD3s;F-`hV~wirwhcE8c8;y*P!bF1@vbBjYq2}zM$Td1zY%P3c zFqeFgo6D1ZPIet6@gWLkzrkg4$%Zr)L6%SWuqU;nEF76rQdYKm8vI7skuk02o+t0D z-OxH^7L3t1dxH~7X2h(}(eXrnPwTqLWsyPxv5!d0!+!)~Wc66e@Ad^Ah6~Tu~0CQpdd?JT+-6xETRn}NPK_reX0Qc zdINRZF!P9IP`D3!uVt)*vEc5QE?gD%AV&BN>3fLu-Gtmk)>gz!#Q(!Vv)LH*WO6~f zT@}n!Q2%Q2$*e4=k9M3#PWl{vsN>;5VtXXIe1C;*b#$38L;MU^qSM3J$hcM~L&CC>JlNaay_sh0pp|!0 z*fGdJD6k?nVyPZ#^{`Y0wJNCRU^aQ<27intZ9OTFlHy8hb810rbSTuR4%EjaCZj{R zPRut$8d{fl0nO58)L?f8omW(X4MVd+iPMLR)}CBDy0qhD+nSSWic33Av^})9=aC2Z zKFE%#df>wSn?HD+X zcoVeVg;deUWF7|K90{%ij_Jh97V3PI_UH%&C!ifT*#V(ODkY(KoD;ZRF7Fne=tb$g{xhEEi9bah5^D}PE#{GPGd zY1a(3I~QhW&00IDqNTbr=qt|6G*H-#5$YL%z^0g3JY8Ex!65Gr;#oM~DiGd4$ML8XO8u5?l%P&_xF6 z2pWMJfn1%)`UGfXPpxSx8R~8Y+t3Rf%n(uf#i?&4H~~qiEPBiFFj%EB{Kr^hxwmS| zspiE$>6olMmD;m5wru*y%&O*CYRqdKyQa3lQ#vcBZHJ*(KfQhboPT)-TgTMb!+v#a z!P>HhBc0<%EjzHl`p^TJ)9)!C(>yt(kUwE9s+(9advyA?O|FFxEX>Yd)IGE9;gOUR zbA&E-G#erGtwH56n_8x10m5xhbdY7nGbKcD@@Oh~1Uvp5VUU&G_8VodK&e zpxX(Ptl%+$#D8Qm;bsGL^RSwSRa)4khEeKDHJ&JkS+aT=u4mv51_}Xm1O!Az+6Xkf zE|k(n%N*+T4hQi*EJlY$VsUWlA%>3(UdW{)GdEWhnxcUJS7H@=PNQmxoLVk1ZsyLw zI=Draf~D)L-s^w==wsm`v2M^aUs-x{&TT&jW$O;$08ZUq=E=rhSD6xT_nsWgcxlyQB+dIxb=uCe&*Um;jPqHrC|Fk9$`)~kA4@g z5OzWczkdgqcw7vsCRnf$ESOOS%0fqDE9Cr+SAPcPO?ia5uneVmKj z15RaDA~wYl47$@CI*HpM8Ai!qN)d#I%5`ugW@e0%YOhV45W8oPJaZ+PM5^_!nL%2?+L|Mj{6=*-R! zQrPidJ@wnqpZw1$<2Np@@7^+h`G&adna!JzzSyVhkp)tt^3(g2v@g&;*(FoESwcOgf?OAsXoo` zAq<@RwLK4>{otWpFQXeb&}>3II?0<@N;AWe^U*|v&XK%H{CDGx`Qj(V2(dEp3X^zV zed8X1|MCEzQjmwhdl8?!A%28Kr%Fc<RsvF4$Vc0KXQ#sZ04Z@Ym!%^UViT5@lN-8bXj zx$}OyWkyC_p>JxbfAsRl7T5N)PP5v=eBDD$QFm4QOiSwvD@T<*aB;8jZhzDM)@kF$ z;7cm2)vDAMO|H!@S}?(z*RXd%vZi$_fuIBV(UY;|TYXUP1(`R+i(4|F+6po&R9m3j z0zTbp-Bum5Lk(RjXy%|r2Kfy587RQ8#{u^e@!^2^4w&QsVy2sX$jLjg(-}-R(~@Oc zMY;kjki$uUY;!xbjLjjD4}XgWQCJgcEeZyrsp=Av?q7(XLfGdMlb4CJ==CO(%fZlb zP;k)!4-J;II#(PzyYi{{OLYs6{dn-fuMW@t$Lq4nuIHN$UkO~_$g~@N^IH8=YbL=* zYfi6=wY&rFSDyjRnU?0agl}IgzwcMwWxqHLmEZm_dhIDHwVy*sGJl^y$BqhPuGR9b za=e9uQ7qV;bSMKkv`VL1Cv}(^4Mr+LF#|+mQ>P;LrmgPMB`JZfDUO&TL*&3d8eZ75 zc+>Ms{BOR(r7!C2nY#Av2d6WY-LJOg&Ux^SyRLsG>Ax76Gu9j1_m|%5FC<&T9V4yD zLoKlhTXJAc4g^LNj(@D3ZR$K8zBEsdcMh*eCkj1u$6ZxD0L|clo9Cnv0 z+1`MPlK6nwVqzB%5988cE>E4le0ez~`uJs&1Bve5dVc}w`5{83GbQ~54+XLG zopR`uLp}>ywUZhFN(XYdjPvhhpXAPo5j_0wUS=-E1C@j4Xig&(ilr!J#7$zH zPI-?U%UQWY#(yao2Q7{jAE5Om!gcY>1N`NIoNQuEQ2@H~NdrdXU01KhSAF%Br2p7I zesb&>yMW&J8A5G~XeB(fB{uyZ9DJpK(~66PZxo1=aZWmkSix~W$U!Fe%h$-e<)`Hm zxm*t!kPD0g5oZm96Df@321q5tPF60(G8srQgCK!x0)LSro-`^xKy1P85RcAu)AF~l zB4Qy77@?=3Zf^Ymi0tQb0mZovTp(E_T#M`9dJBIBD6YfT;wnjhd@}BhPbL6gbYqb; zh0vu1h0(>>?#*GS&H_^wY#j;ZBj=37?e> zpv3`AHh-9Ffr(~FF_oKeqZXQpGG$>a0*5&zEhWuoLl(Q;9&%ZHDJcdYa`7&wi*dPf zLO!Pqw6b&=miZhiCe7}!SqX_+%m@=16Ny|I;N!WuR|Z5kI_XE}CZzfL?tuZY4DxhO zS9<)nFRxg~QxrWOLijAP8fD;y+$a-Cxhd_bWPfK@JpB4oLcDKDQ$OIx8c#pAer|Zx zU6Ark{QJ&^AHO*`wgOMyda7mFtKE|)-QO3TzVdC*96ANgx0mMBZGHZomA%5{df`nN znFDDrSN(S9p34WORv!5M;~V~C{~cmp>fbY;5$nW+f@oQ+G8!lk;Alp91}=0|IB=n* z!heE^Q$1JHq``B!CJx(dCNCI`iIr~<@_G_!$QCMDrAg|v>v@^k&PbKiE~V;@yoW*! z)a;DhbQD~KYpC&&&~TC5lt_LAhF!Wu*O||bvN?O38lGJxWvllI$Fh5=voV~s9`bD7#+u~mmA<_;%2rA0i+i(0CD`-VDlo_+i zIfFN*1Eh26KG%J(V|50^N$hf!lF;g4F74Hd_=Q{=Iu?t}MpKet*F^|aj6t_PV73It z+ZQ&3WxX)cU+C6Jn8O^GQ@y5~6@TMRQ-xVk4__jWpou+7ik`TV+ylJ+A_cRd`DJWc!M88Or?;eUtH=Bmul z)Mc@;O_hPHX)UeWrako0Mxr2R%$UCYA5FffTPHotNwZ0pzlb#KUo!8p*3#(GLyh(O z8*(YUH3ST$l95D0XT*4=g7ZpPti&Oygp-PtK5(9j=JNx@iBCB2`E(3BVsgXA6KBqx z_{A@nM|T1z{J4{@mlkF+Uw;zMErce=MsCf37Hy{%*JwenN8Vu2K2qsXDAI{T@3dok zrbDV!c#E+@TKcl# z=W8whl!h(+CYZh_&1nn>;%QM4G7aL#+#%O;E3cyHwDw+@i$wN?0T9mSSmE zr(=f$*ASDg4Ixcij|V)SysS1S@o9n%DY25%9R}j?q0*!aGaRNQ;*|#3ZZ+b72G9x$ zBDcjYqfzE|>R7R(aer4`ks<3~{h~v67mw}y+4A<&_l_%Ad3@dcNhQrwMvR!+JZAje z(?VI(mrMHhv^=_Iac*wWBC=d@Ljp!;Tv7%PQCe=ouC^9KRO{m5cXfZ&O2D;Qc)qi-I8nzLC7NxfJWJ7i~ zUvQTbW;?;>1SbK7ug%E=A9B#-d@hGcA`;b25JYJ2>k@wMKLNoNEs;cTm7>YeqRf!& z`%u6P(z_=#O)bhyS7$#`zxYsV@%XNnm$#o<7Ynz%xNd%aN%Q1TU{XWL_?35rv!=K1 zE?>29TG?1v_J8>CYmYQEyu7KhYWrJj8{Yl(mm3yHO2e}gPzX$Jt*BT>pz#0Bg8Ba_ z=ZH6$%qdH>!DP`JBrkRayMky96FL@Kpw$=@Miavt*h1+6Ld@jAE0G!{(n%61lz>bE z5{aSF0Di+912$kzu8@HOyhvswcR-yAI(bon{R)sPtbfD^!;GCX859bGiMVl68FAfv zC2Uep3=oNu2)Gf21lBOcH8H8Wle7OM#K<5{jZU<(>cmf>jwdFEWji$*SvY%P>OC4GuadG7rP`pm8_I-!c13&@QRexf%v5`5WWG=M z9gX%JAb%-~-qeumzOarYtW~I+a+7Ord*5LeI#< zBk{0P^r2r-$))e0EQ|0tjg!kBR)bQtVn9 z0e^SdCCZx-@WcRRLYmdx9zleguD<9D$$ai%{w;{I>r?06`)ot^g`MTI_kYk;|Jcf@ zmRHI@uiZYMc($9TZGPGbt#cn}D42cdQumIF4^7FQ+g0WIWYqG%Z2rZ$T)x{^2Eq>kskVM<1d5Db&i;1CT_P(}!7iGKzp zekd)+Q_l#GUAlci@lM6^DiQ4hzpDpU#{mPnQ$Fk0>!(VxCoEiI=Vu$1)sZ zSt*2Qtp2!kNCGDx7NG_#or5Aif)FKhHoga^#lPrhLd-|Pxx)fS?wg>dK0-|{LQRvl zTET0DZVUJfTMc*{4-IO#Lk)$B3V#Kj#KLG6+5ytj&1o8sR_pSjG-p~Y?Qj~KX7&;f zM5fU?LN1q0XD5slI$^V86uvdUF?iDm_$LqBD|HPKlhYvcxrRxJj?TN-zORLEx<5NS zcjjaN)dTyhkB$}o+HkNjQrNVAVgIATb6EB0i+3Enc>ktP56uyN?zvF1;(v*SO;6oj z)X+Z!L3XZ)zwDS^>6K$FQFDw}!i6wq6*4-^0W6har2~2qcnL%eBnJ0fqH*ieMcBE0 z@e}?1cxoS3#D5^PQUvD`cZZqe?hHze$r(Zh9}+TP#Gyip4-g5FR+WO8{rw`mgEzjz zUyvg`3dB@}QqX&O-YEBQdVlhxQ=D8WG9gh5r3wF?(lLnEf-gU6P8vn{i|qNE?|A;D z7ntWqO>oQmp{42nu=gbZOLE{ zJOmKWDaymm-95@fAoUQyUdDsPM{SG_C1i!PP=E+Nuh@fp)*j!CZs#J$0sQ-GVej8J z$u9$rkY0P3Jr4@|`hW0e0|aL#nwep(5L5d3_?kYfI127ze=3vPPvpwpR2H&aW_|~8yx&ZQ9ka--Ca!Et-FXu6X|I* zO}pY-+u5FT+>p-A1`(B;4#{K3k`KFDFm)gF;TCSY_(b#+eBX~LfAi)xX7hj3BbY6M z+8gV^8tVnMWY7H_a~z_Jgo>fYXJ>UpqYf4=3`Pt3pnpui5q|VYPn7A2a@|mx8%lRY z`7}zUkuZ`9^a*4G1%ZKZC_o4!+-0YYs{`39mslE$+X_rV!;sbjriB~^Q?aiRU4J6@q!6Dp8$n8gNq1w~B(KIl5;(A-xr5!tNEL<2<*qHMRGbsVi zH6!QhGP^425o0H2jEMIoNUvjl0i^rEzWze?%72a&G%pz~NJI-_QEHGfh)xe29!L-N zAL&nzl%fnN$`_z?0V*JXhf^$zuT@9OJw+nDH>v{28QA;_BOBnrQ;jcZlfRxRh>lK^ zM}`HUfR0Gi3QfV`@r9w)p>!x49PB5G_w=0ajSSvx-t<^+G}0SodZRcXHNXvt+`y0B zpnr?Qh_D^xE_0Ko5^kQ&7>jSIk9Aypfpj@}EI42?ch7cg3jRe_cbXeNtBRlYkLf;D zNRrd>T_OBV&>hyVDoNHSr>Z)JWGx(Wut*>Bh+ZUqnTrh;1P6OW^mU8kf~~() z+Be?S)t!wOk%h>eEJS3*Q1;NK?zg>$#R!kGi-k4Fv7 z8lhObgAUepHV^r)4bvvxydMo-uyopjuFWVtZFszImk%?ERkc>Puj#`mR-)ocU4IFA z`)LHs)Be9!bWX#}5iZaU3eKI7YVtitj#t33!6hlKIgM-~7DFv&b6@$scixedmh|?m1 zsSuwKIwV9EAqx-$r{QgAL~ww88-L2#oqNoidk({K6DouAo6Ej;-a$ptj@@X0^V1mk zMhUkGj7bzYwyuIK_XV>CjVp)=E|@y*{>~OSN3Yk-dV5YjvxON{J2^MIaYSstk|oyq zN5{kuY5tQ|_uP~MMi8bo`o|593QvxWlt|^pE!88Y*CY?pFRt{=8apgBNPnIe7n3QE z3-BLOq8*xVg)?gPEH(f4oCRN!6Iw{NyDN%21&41W2@ZE+8jpaLih)KLRhykw6J!XYtNa`M>4!WJ9ND;g0}l#OixACY z&}0UMMe!Ji`|uGd)CVu9eSd>p3C<~Zji#{YU;s9TyBfpr8xN+~J$%@N)#hpICk_e} zye^bPWsS*gXdC9c6MdR$HET!8lGO(Dgn0VVo6Yg%BXg316ty#o=%paF8_bRIAhkE_ zGY3~8R0$^#k=TV1&@MC+g^O(8LY(21lJD#a5A%|Xb5kbe##M0+!ofXow` z+pxi@awxf3Mh=$Um-ESv#JQM3u0i16GoJz{H*Te6#&;?9bqzg$Qr$c~+=R57)Enh9 zlYUzQi`PE?i12V}|NLk{CPqAzqFe@p>`^E!duxmj^6?UT`gnRpi9Mxa&&R|_EcRUB zi5fjoj3@FG?Fc}z0e>hc0Eq(7GIxaURL}u|?xFyZdsJY6G%&zDa245l6pGLQ5$X#Y zkiZdvC@`o$sNEk$5#=ew1f!JSpkO9wH9@5T#&`3!WH*)+RZrkAAeh;&h?W|&Y{U$G}!BOWIwn(TkS7(qda}xC6uS1kGsU(8|OUSB_iZ1 zb&kPv@J+@x+%?h>iHyCeX%jZ(1}l!g#(8Cad<}e>6wHKZ}$OR zr;noJU3DkFk%o%g1|W}jyQ)#rkaDR{R@Zd8oDS*Q9-QbW&O+5UFF5P#MGeUgb%_!( z9t`q|VyVp#aS?x=A7B&+yhzXykZZwyT?D^3yLr5^WuPU7+qJ)j;{36 z*FxmJ;(z$)>wtN4R~Y)7UfT6Yd{O_9;e${U<{k#o?Q`JnOO4Ks^l@bv1|4IN7`TCOkl@d4D)G}~d#%CTe?GukLA6`yQ#y>oO5Z&$D%}Kr~_$jmSR0P{O@`|Px z?HVrl{Khc4Iw(5c?`E^WaC5mdHcCQYT~DtIjekq@>+HN)+$SMcdg~Ux2ZHK_r|4+$ zBam~UK3-cw^}&Bvm2ss7IS4VY3uF+M<57Gn^p3doJw2bkid@BmP{pkd%Ka7S2w^fc z6<=?g2oye{uLxYJD-?CJKjpfG!jh9Ve2IBJY5U&Z7Hn?|2dW+PRcN~kZBe)_PQK^cCPZ1gUS$B^(J+(i#D$#X0mDXdOygVPrr1$V6ycL`DunWBHNZ4p~(|*F;8U zq5HUz4p|4l$eCnhHY$fU(N-E!K4d6qPjR&8pemlSzk_ljeUM%xe4pb>*O699jy`2I-j%xzI>~Pqcs3p7k>+Pa#+x%9Qw5L*g2#Xuz<0kkr&Ntq@vH# zCejAla&3&gZGb}}&=%T=wv2$&7XGF2X$AG0J)t;Qa}J?Hw1lpu=g}MKZ<$bLrwipe z#I3=7wZ}10y61VXa<7M-llKq4k-k^__Dd=y$D|kiJNuLeP<;#fJ{M%^w;;GNB!4b+ zQrM;NqY;z(4~%S%4vD!Impj14ImLgS5Ro`DX}kPa#le*DfibCBY5mjR9rSqStij8N z>>he%*tc1Wb1vlW&fBZ>DNIl`jJRGT{^Qc9(0^dcaipgl>B#>*6$d*~)?b~Llz5js z*PD7%Z~6~SZ~r0bbZ_cS|AOhqQh)E#xZc#8dQ)%eO}(i%^`_p`n|f1k>P>%58a>b{ z&FfA7Qt9E|)SLdT(|cS}yQ+2SH`HI06_q{vcc$y*{mWmjm{9RzWmx5Nm0wg%uSV7G z)qd4M)e+SLs*|fTt8=SIRI96hsA;b`P+L&@aP8~&`QP{6n4x1dW7dy3Gk^B}v2({> zx_{#R-;E0zH+o#nxKrbc#=of%XmT}H&AB?iy7;cqM#eW1Rren5Ru z{c{b%hA$dx8=q`E_fJUI|8tYU-4I}iGNc%C4W)*0h9<)d!y>~f!wZJj|IN~V!wJKA z!?oVjn|f1k>P`QtiK3`X`hQIdzr}}NWeg&}Y!v4aJy z5mJ5W-F)5!`hU#lT`8TTj~gYYf8z7*)Iy;PpBH;E!lm}#cZ$T4$N4;>gwi#9o~B%- zpYwSE6(K#s=NYFyLdsKmjnBJKuKxDlq3TL09DUrVzLHgZ-knnVyMOX|u`BIggx|ks z1i;HPxR~UHkoO6`pX6Ogy@}*qN&QrkcO&_QB<~J_hSHb#Jcl8d=P=~*9EMz;aq7ci z$mKZfnup-N=_-LbjX!cjg%g~M^R?V1V1*ajcO(}c~G)I9)D_}-avXJLQ4*1 zgv3&6sB3`nHp)s$did5u@5%6~BR$2C3ZYa7wR)-*YDx%o6Myiv^C<%AZ9uyP=&(T7 z3^Wat7V=uiH$$7n!H0E7FQ-x<7wsseQ!*lh1}HQ`Ul#akfDfjjr6%%yM?k3&YH@1| z$Y^!wgmEwsJ&gC1r=DQJQn^sBgBDz?AxQMpk)vbgHDw8x7HHKHeQ~KCXt%;x3#n;= zUOIvt3-xw;sDD5vjE;efGZAbDlks}eLr*mUPmHvVe6qYm_P#8sw?YlZui0V2Zar|j z4Wux@NGqU_Lwa%=*|pFRnXm`w2uCdQM50~&-{d{F_ss0U75h*F;9(?uSSl9!8;AyG z2X1jxCBe$-&?g<}Vt?+YGzuj9f9vNSwo*RvgjVQl0z9xC>meC< zoe~K4W{}4~I24nXMySDPT8V8+i6>b|i-F9cGWhJ)9b=}TGN?gd(K|gH>)isfG!rd3 zed~$5He$aTf-y^GV;jMg!@%aStGzd_GZXK^=wq4mL_Qtq*UZ~rM&`MR@M$Jeb7QqU z6+K_p5P#auM1v;iWg~5PR2`ASZqM6oW8+6~o?^M9rrx20%u(+4jXTk4CS@Ir(L!0q z`w53?D){OqyOLS|1J@gMxxA50`-Xzr;g z=X;tSUd7FPGylnH#pQ7fYUU#mmey`fJ008;$GhM2Q7&qmc*}HCx6cp*kFtftMgy6{ zHr}>)uVP;%>d9<25-sg0_w;HRv5bb~b-W+k8PRT^39%%yV?8seBuIJ^kui^nByQ=6 zRev>5hY@Ok9`?2*p60mQqGTLDd%L5B)q$8@n*Yl>^jF4xHuyFgMRpo&h{KyFKpkf% zyVvN+nrYSNF zWY7@&IXm0^nDeVi9eKNc1(3arWMKk8ZNt zqMIH2+ec&6xOnQUw_UF8-B$Ok>0XKKHk6TgZzf#o9c8_fhv2xyS;z|1x>s0E>VG;S zi=JPpS{$}?jwPH8lX#0;$t*ECWU$Zcp1$24%_dhFQ^c-a+v4XQz9k2J@*MD5iJuGT*Xm2H6Y9iFRS;Vcp&MW%g>H+rkt&mcZ z))J}!N>#90s!5Fs>hQi*4K0;W%7@x~sEL6dWqf-Ku~ZdVhYF!z1zF=b8fy3~hH?#w zaRn4h%D6NV`WFK&JXT3n6CO&SRz`ZN3GGo(TLj-qz8@Zu2Q?K?#`)nS3V(9^ieVIY zT2S$8A}47%)Uyr^drGAu9PN^gf|45O7xJw+KwCxVVfiut0+KIw$XUQknnN(clrhab zkf?~1aBT&AmqNcX!as-T%t>2JbSQv!P8TJS0CP^{b>;eDd@A`CY$GgR5u|RdatH>6 zM4E2=^5DA^B**lJLu)x%A%99>WIoZfjG(9FF~iyxky5u-oTc)JHW*cmK|bV1!Ow69 zc53p;$)a|m))Tub(%#*R(=Uhr%p=H^kP>H&JW?trw!*D4-j-^j$L(CJh$kvZuN)AZBrP*xJ*bHVKH@8{v7#5S4r?AoZD_zE_HOA&fwoqfznza+5 zc7(an#1^*bte8`IqkqB58lCCXn=Ndvq0VT~YK$z;5&D>cDQh*iShRZhs<*XjEPA%Z zq|;ki8`eWr&K4Q8dXrT@n6>KltiGvEuhZ#utdXl_b$YATVra$+5*|9eO=B=x6LTyE zU<4dAtj(g)>6(=4Rj0>l;y#Uf zV{=bLVfvWb`0m&sKoIb0G}IYD=0vd=J665fXfzWS;GveWbs8(kYBo9C*=~f`Mw_iU zGbu@LN^CVuG&JjV22G;b(vXBpNzii~@Az?GUg8#3EEpzp_nCUP8Fqy4QG|OO#V}7W zgH9M4{eNV=5oRBOyXRcSQ1+P3VsR-pj+J;n=nW9)VN`=f1IXxPY`q0$CU}pwQDbQU zoiWCM6<8F8v*tROktPg^hC~y)pZ)b(V1YDNs~Khv_79y|+tLIU(QuRAU<71hF~uI* zvSoZYIT}YK(&=$L;OubMer&73)`+W}+)c*28-JGG-fT30pK`o0EejV=fdiRDSVI}x zWY!t#@wc7;(%b?HSsTfO1=4jbc=B3tCGRDmVG<~A)kA~^3fR^>N_Q2NoAAJrn>0Mq zM2OZ#bJOqWh^Ik|#RS6W2?3oM!Y+|zf?jL0J6N|LgY)YQWa4FVF0QFFPu4rF3K0MB zlz$=e;7Qip?J0bdwNV3F)#-c8T#b{W7R=si182g47bY(^(SHvBJl_hHY*|S`c~y>D z$*RiOQgunCDqoq;#^jViIY!1-smcpWD#}^tq0T8TuVG6H*qq`TcBHB}U&bn{OV!G< zGPXp`sz#L-sgzKsD$Xma$X68)XLDg(aeoOcJ}Q`rK(xGs#SD2;DrFfaHcF|^D}-WB zuBu2?UL#`*ROQ8(W&se*VM}w=<*K}jq8v3_TA?m2DN_Rbd>~t_DlSk17v(5rad{$e zg*sMQ2?e&SFsG=9u*#_b>D5HOypqxywQ6`_Ia^p#l&^%!TqQ`BlUt;Ad)x{7qwYTS zUTg2Y*4}%q{hxoWox5M!d%gYN^LjgHz20l?z1Q4(uetYLbH6>B_g;7JdEMQPPVcq% z-fQo@*WUlduDv^*U^Qfou$Mn4Ct7`v6Ry6;8J3)4nNUW-jAVv0L*X+6dVgym^5K0t z7q1%8X0%2?k@$(vw-)jg7^cBLKTc7%VyGvmyZ=M{cPxIITW2&i@cBMgES;Q>G4xGd$^h1bj5!|Pn!2Xqv6 z{47SUbZ2{b8B~?f2r0bfVt*I+@g0RoFJNdSq~w!aJmOstgWA(+#B^%q8oA7=CU|Y= ztYB&gNhKuMnhB72aUO<~TyYyghD~dqdwB0t59QuCX_=iTCZy|n{hopCJ`P&-RC$N-$dm8kHSbUFJA2eqh6gHM3Ea7C`lgn4)s@7Si>@~BkhVv3 zmp@-2V7P&0lo*y;s zfYM`BLgj`h)XY_vWpfW-e|6rHfY_^NPtBWPeHzIwezn%RKY!Dnrro~?H*I<;d-7<- z^*3huE>xBczP?v{_2B-K{yW0n3SM}1!rTdo;zrS=gBMeC<6I85<$2`&C3I8theGA< zkw3pxOEr~mi+_p8Zit$;akKEy^wR#BOzDN88)XU8L!bEQ+_Lj8xYGidBG0s=CP2g> zmjIR_QH-bD!^I6;TqtxE2;?ES(u?WCNY}Z(S^Qf~cBZAS|Ha0DbKmA4OaE0~ikp2I zm3;U*r94j&Cy&7f5lNix*OWBtIdfRq(iXkNW@gm}t$$h3M=r%(g%WXcN^(YOM*P6E z^nvLExi!rgu&NfkNZc1vNXu!2e{4FDE5=aI93*HNkI}ST;f;>Gzo|XumQ!Yxn%i1~0{uvnKCVyC0qT_PQrN-oE!?Hu~4q8?FT!c1OJW zZGYyp$9^&7o@EZbT{-u)WT$UE>3&v9ghz2tcUYn3!dbn({Ebi z(X`>4H{|Uu%@FmfxrpbX@l+RaulC#?=w{FVLn2ACT+T(3xbAkf*$kb)wuX9xR%6q% zIW4wEv&CR*bHqIOOqZu6%LmH2n3u{GQ-5*spB|I{x9Inkm#(y};nh9oZn{%NPd~o# z=gP*f^G|-Tx4LA*vy-PcDR&&rcy#N!&|iPmx1SF`-*pw->txu79XH z9x_(-)0P2=$LH;=$@*pK*7!NLKgYi^xZvFP1**3L>dOxVzY(&hqOQvFOT+6??7*{Q z*FU@L{ug6sy?=bm(-#DT{hR9heq8_YXAg-A zTTjdze%$BveV1PN?x6_@!ZG9bZGRnb-|GIseGN9D7ZIKW91$Y;-%54E$RQ6I%US(T1dCF#ssYf@fmS&~j) zuW2#b5*uwz@@&U&T0Sr|nGJzmFn*f`?_0;g8O6+B0cnF$8Gmg?@3=yh$cEezbHTtt zwkuU7anttnnKxy7>CuQA?tf2hY+wG%z*_@k%a{3GIKS(IU61WQH*mx0+1oz}rQSS} zYJTa$%(i8%7wBVGzd8ASacDoy+TFGNgT7z%eBEeegWI{RA)$}`BA*wqKO=knM_#Xl z$6a`KjbTy5V+U<3zFadr?=NK=-}06lW_BHkVw=pGqo2ASKV_k0hJTL9Lr0%ppHX-q zUDM=xrY!Ki=T2yL@A_iSi{772T(#`PjM&ke7mOIaZl!VmYhfdTybK#Y`sD2g4y&49 z*!EvLEyJ||*Vms|yT0Sw=Y8^5X}4`LEO2?Zpkr#^tV?@C!jDh;mF}OgH|M=wAw~Q9 zTzPr*%o`CSRSQl2=YQ7EoP6KmvbIO&J$3xZ>7mxtABJoy-=ZEq;jI@W%Z@De{rJg- z`;!;_mOk(BCoS_vtc-9DVhE!}WE281!6ZgY|<^CELyl zE0<6G`78CPYpuePdHYU^t}ecu>wZ`~`CR|XDG||WZ~pn^MSrFjLe9_ocz8Jt*1}BU^mA)Wn!GJ#AA8Cd>-Z)-;<;3tOJ7;Bo=Rdo3*y_*9 z`UaJT3|h7-v_3@=lMyiG!L&og?~L2>=b z|KxCe&uzZb>7jG>W*l~SM|Kw|Je`jxAW3&gr0|kExBAPIx(70f2!^Fcw05{Im(^~M zmx(tm-8=Nb+N9U_A7eU}ULP|oavr-vp6@i=Q;{Yg*ncUV<#*?ev^BxAg7A#Ca#Q-Y zIeps-#I!@qm47`nukzca`32T3uaWm(}^T#$?M$g^hnYLot z{GcJb+8@30r)TDVdUeC;jH#IkdsJGZ=XYx_(q~qk)^7Vi@ZI${&*|oL{&e*j<9gR9 zk7Xv8cYlH-7VR$B6?RF+Xx4Oj$}gy=PM)%2)|~B$3xC^?fA#yl#Z~WB#w@-}?;rJL zZp`uie(z;z2OoR?t6#qKii=lln|=PtCpqS z+V|&29A?|8ubN)G@YtC}pVrRU&^5hi?A7=EHh<24`bf;hBVJK`^k+v@|1c@?(5fdI z!oKeJrO)Q7m%pe9RlYO%lZ8V@zxvxpt#K3AwEKM_Z}&UvfL9j=a5Qa4*?{d3Xcz?k%#)s5;~_wIIfHi2d~|N~!RnTZ+3uAAd(f+J@;=pl@!d}RzKZK_b)+tQ?ADA2wnq=xkbm`g&t0fC zbId};(jW4sO)u!TH>I(5UQ@;2y9)*Tf%STvg%$s(UFbb%-+s=%%LNU$yB)qqi#DAp z7$o#h((QU<*^Db}-shivQd@N@Eje>j%%-DXUmJRT^e0cf)VQi4vEkbtn)`p;c6jsA z9YWWKL|bMUE*^OQdEaj?{eL>(ebJCA%di=>xAeJ7$8UXeamv##U%zQJe)3h<1kc^0 zj_rzPE-4*^%ztcn@#)%VX?y$r zWv@1W{q~~&S=Xj{S9G6z+H+=2_vLEZ6_Ps-q^;*p4iUDwr$(C zy|L}&-Fxr%y+7W1=EpN5M_j69;f-?2&Sxox%?TYmUO!d;7t!31@PrBf{ zv-_QESiK_5tPalF)ros?bKD%mW!`kA$5l0k|zrEZ&*-Sb-MnNd2{ZQ2%aAb-Yk!NX(LAGKo)j_vX3Loo|S#hapLUJ#0~Bf=J>ReI<>r`+R56sc#-1T_(CF{=#K%zkjW^fJ!ND zUFhuI`QW%ZsZhpI_bQv)V}7?EkFnWnLO__uKx4+yo#M5+)7~~&zGZM#dZahtE$QKE z-8;|bgOY0-7z&#-0E{2hZ-Ww5rhSQSzuPV2Sk1DoJ&2unFnn|E6x_lU>a=?_!}IHi ziRMc&*wz@a=5f6d8hoFuPR@L>Y`Nk+%TN6B2|AL(w&r(Yy)a(-sGb&3Ip^y#%sSoA z_S`ZJ33N1vVsHKav4yqacqr|!puUO)1vR|tYB=yU{2qzI0c7U>IMlh_lH3`1{dgEY z6-ZqcTOIdG(>!5g3N`42=zdoJ7#mthr)f47;PSa#FQpFlvIE0FBTK)tOHGzLi&@yH zzhD^e_kR)7Jq3i9&%V|l8>Zb{mEJ4XcM%u_veHx8bB_QurH{>g-3^pQe9f-7duo|1 zt;!Tnx2Zi*fW7&u#i}v?@s|Ofc%j|%gxz32Y zK$CIs5AnT9co2sdPXT`8mamOi?@{COtI|s}2A_XENg5v?x{5l6E!tNxTlQW@D$g!k zR%8$X%8stfze6q}7Y@n~x_cZr&htcBV{rb35Ep&<;Ha|DoF9`%=;hTaa0<8mPN(yI24qPv0XhpxjT5JVY zye|2S2DH}%=z_D!uO5>gkh!6WE(HUk$jOzaZ;r( z?h>(lp_)AYfjd3zwP(FDFadkc>EI6}-2L^7lFRr|`J8NI3wrqD^ZXR4hNqEbu3T#T>o}V|U`S5_lJNwGy^Go0%Xa2@Am=wj zgi!Q(!I_oo7Q)xj3y;Nz-%Rw-2()JRsfLKK^%S?4It=)d5(}gte-FO>&uIXti`!bV z=prgfW3pLKJbIs?Lk^ziEau~Cy4)`$n=2#0&sVk2QLHl3@?qlr>^=#zveGDvmbqby zP=?O)+ePVU9Fv+dJ}P(9xNK&~YWTRRuI9f}1uk63I*tIPf#*_YEFwT+-2&q@Q)jLJLNc{*}jX#P`g*b$9d8ztK)C-yE3lo!}+@G|hypNuOT1r@+B!^E!j+1qI0 zroAa%+(^#m5L zj20m?2d54pJdBC0@qYn!E~aGrKv2qLqySLzdrb7faF@7&*Ym!NJTRV`6LOWX?p$!OqFT%+C)G?*G<4!F=g(U; zI{WKX>Ci)55@rtFS%-th&Q!(qu(B+2=BUowG@R-duYu`p@?Q#~tPhJpld`a%9`=J^ zm}lT_3qq_S)l&9G?@oYrF+)ewL-2A_@fXB$^^X&y>Q*10`JYk?i6WkTVcKWaHf_0N zCsW5H#{`Jp7i))0$*ds*(IRdK3&9oM_ zaYd0HN#?|dF|Ymuzb4vsdh_XE5Lw2xV>jgc!MvUNt>LWDjHXjmN|E_5w<*Qnl{ItSY41)3K>fb4 z(+QuT(G+sd=STt_#<8vn&G%N8xmSWcn?MsiLt*8P&~?ET%aEp$E|VKe3v`EMswCpb z)qFtFk2H!kre&R@Lyv49!!^OD+z+DrW!TMLCiZ-O$)11enZUJU+U;vhY}OGQg)^tMPe6h+q^$g;4X5KAy;$xMtpj*RQk5UIG9-E#ZG) z&~XT^zQO%^&H%jb;JY zc-sPIcfP3P;`tSz%#|i8&aP1DdIBiO=M`)mLoQR_Dwv~!0(Wtbm!xkFeN`Yb5ni-ppDHoCoLNIo=#{xav<{3m@U%4ZD@tQT0R z(M^Bg?CYIb&EN|j+>@l4nsdyuH2?!Mj~|^bJ0HMxYK+;5qF?sQD%MqT_s4zdKE~I_ zzbQB-G_~s^5kAs!W9my6L^?U~4m&T@aDR_sM$*;H*c5*J@h{TBK@25jL0o=#X<&&{ zO?R2c2H8G^OvMZG?4PyL`J(wk7KZY2inO~A>yH@8*Xi<4UDPY^v#;Cs5TbKdI z^Y=+ggp?RY3@tS+W?VK0FUN2KA1w__f956j>B0h$MJd&&WEk|#?^>o=#psdmo^C0V zmQ3lWntPEBWjg!VY<6P#>QnYn1lcrII-XMiewW%^{=uaMVG)hdrk&$$wL=2M)gHazEIly8;XzYP)( zO`?7^x^CPCT`WeaVpg$CsGXEqHys=*6w|>iGA?vLS0%|MF(zT5Whr{FSHaj73@hYH83EYUrE^y7MYHH( zi!+dwEXCCyRkl!*R`-Dn_H^cH%14Q5r-QhP_!C+OvKsERH|x@H_&S=+m+xDsrJdZr zFc9G(I@%HlZt98j=~R_CBz+ zmx)U6tEMfVmf6!;cLQa}S_vDMg%%v#-lL-)@;TY@<&BS6&h*92w1cYKDv4`Y(iii# z=TdWx1+bnDj@)>Pg2OIiA_!`I7f0%8(+^l|!a56q@c*d6EqzZk?d>lboOL{mFc-fkYTFQLt1o{f5TGi7g5KH!+nT8rPcOD4 zoRbT~@>oFY$%A+6+!~qqQ0kn@8rMoYW@1uvYf`-R7cMsVhIr$(jq-=6yM6aO6}y{o zv)rBiu1)$cjE*I9-SC)uUir>sj_|CmdcNPu;aN@fd`CM`^dh&m`wheHbXZ59BHVjM zWf;1DO>Vvl+5xT=J(f*X7H73gwaqQg$RHg&Qg&xET)ak>-5JsA>a#J{8NQdR)C$g-6=xDq@x9bx+fwKFR;3$ zwCUy|+z!@>qtvl~SvE|JUKfE>kwML^WBsupmsy$3UtTrrhuZBUmKnpMyQ-nMof_TM zh7ZrRY<`fZ${G$UtE~VpoblE&I3s^D8@3jyyK2r@b>zyzyhdxbjyZXC*vl?%p9g0| zjK}f!1=w_`5f><@%b)yVZ3Sy-25+e~vya5r8JHm_W)>?lSCXOV>cfd?R>7ZK!kb|# z(LN9oQ^2ZJXjW)u|D;xE)+S?Nsnx3Ek>=vZ#id}mgHR*VcJGwDs+;2~EH;cihjB%9 z41J&LpqM+G)n1xoliiSTs6>?J`bv*B$QZPrqGwI}RBwo~CiOY^qw1@=VCc7{H{9P4Z-tHVsfM}#_5s1!9J-DB zr`949CywjZVA+#Gq*-bvuY7J6gpU?mfN}~K41?G#V|h)hb`Cl)7LpMjw-$$lY&1XYyK*HA>K!leod25?Abb*_+2G zN={QB$Hf)-kUh*gX`M&K|ITa+Vtv=PU?{ z2NjriEvnN(t{$%!m-2a$Y?n}=pV{)MZ_^*N-#OkjOQ&g#FNQZ>{Avx@4gjwU+JC== zr;L!?55=!R*c!RIA06Df1*wp%h)~8EL&#qWts5*smKtu|nvVK~1?WjD_uv{;fL22` z``Mv&x5ie3Z-aMXc}2|5!RSKj`dQC`iohb#{cOMtMJN2_YYvh(_%E+#0D~1FL5ljx z3OZ{}i0x+%o`)PN21ayl1D-ega{*KlR)h|z5i$=w^cSI}UkMvh<9|RaLZ|-)SnmG< z=R1J+9q;?*&%a=Ch$8$*FOb9ppHK<$qrSq6u+@U;oYbf~Ce=%#98VwgTfj1ClOb z2V@^?;D1xFU5J0_@=vF4vmhc+NO+KWV4(GEaIN9d*th7XtbZpPHe)$vZGd2H$-!W4L9E~bw_t0s#Xc{~-^T8|NsE8ET?o@J#sJeN z(|QM*?!Zy8qWKcc7*Fc*`F@t6GV$I)tW=}8)XP;zV!;QKNTv4Gt{luFPeOTLp5FD| zX1|DDh#l=3oC<84)tTz~5Cnu)#0+Q`e>NtF!H6rrynI>@#OC@79fs9^Tg#&pptjWv zEChM$$y^Y7?s|v3jT>W+3Po0}m)z!Mm$Emi5z`a?gMo94hrDew#H4HgB~KKU*Qt%$ z=0@poiH&8~TAHVfPMMra`htaJ0L}%!b99@0isVB@^wmcGl3@?DM$me(?%pN43~upO z$*E=0ue=MC&%)W>-w}>a&;X)>p#3B6GspTSo#Ff3o-KNzS-Jp+9qaTzJ^SGlox|Ki zqC-~43bM7m8WD{?I`)V`!@3c4TOw&|*Brg4&?^WdSp*`PI!crL%bh$_J)&?|MAKc? zxDF;I`07;MUds;eyHeAvLq5LE#Yt!nV5VbQf7@VfkT%j@?S9LP3~S{AUz%5a63u=+BxP?4?AsP$Mqb3D=W*gbM1x&SQeJ@x-^pYFn*<(+fspo{j5UH8r_NaD`r7^*Fc9P38>_z>?*c&QsoH1>BLE5 zkhyP~oNt&?9f$1h88gq|0CHnxC$~(h4ymuG)f1Pv_I6yI2v9dkv{f^mYCObrjs!bf z$2f!t6fZ2x%C4wsDrvg)t9Yg-Rn=ed0usY}PY1M34z_1?=-b8zv=0oc9GKKobxkK! zJ0%9ZZFGu*0P0hkBXAQ8#CoD&9OaA$w43OpTH+kfAx;$a!uzp-tUN~fPL2)L-Npb> zbz67a*5f`d6dmNf@sZxD0ac?6s?PJ$UV5msd~GzRrAE>}mK`L;OKzF-W{Y78H>a}O zoo3PySes!goh2}U{iY=&|B=<)+*QHSRi4Rs5*^wgz&x##hi&(Gk9}2AS~Flhq!Ok2 zV2im*0kM2FjOWFM zdG*^Xh+*2z`;ewBxNY!F+Dd(EBxm5PEVj$o48-)98d62VRpC^zwZz)VZemkoWA}38 zf|5NKaGrKyEn6R~Tu5%#$y1x2tB?NK*oZ$BtZCRa>|JUxG=P`4ceCJ`#N4m7KG&<5jNRXywHd4bHrFdygVMX2oEb!i1CEtB4yRxryR+E3r)8-_9{l4|BuUMK zYH^2xN_DEI9UUS%)8s3!hiR6A^a~t|k8UIY_?usRf=C--u`t+G1pXRMR*TFEqWDUN zzw0vljn8-a9jhT#bbpgBi@p$ACOA6e(l7=x35vfc;$*mi?V7ipt_JMmX>R-;jrN&i zgDJv-`JSQB^i_jf?!ixdMCgnX?#g9egO_bq>)8tg=dxJ#9@fQihh_p>y4j#ZiMsd} z=z;ZP`6KH(ij$bXbac$WHZJ4$;wS2+ge`Tkf#ODUO)-|^;o+YZEQ`NH5koKdV_A%Mj~!v!IHq`T*CXqPi2To%1|l7OcG#LU zeV}=C*RR&k)tvodrd*@?`F^zifFf}f_^j)Z2W8l!dv`ZAdRu{&@^hH(sq`BLn^xjH z#{!9w8RES=cJc7@5e0I)Zx{U*S+k0a4wE&o=QSXCKhfp)%AcuEzQYe&;^<#6uLIN^J3Y`%Z?+Lev)JuAvu6~v3zlU!8<@O z31}TX7pUI^y1%f#aQu$I>x;0&R+gr>L@*i7_8xI>In}%Jy3zop{t{G#y6syC@3JLdsyH=Pa>RE1)Gd6 z2|u|*so6>6^{2}S)~&sJAg^c^8B`4m#2DF_(*c!9@onC1Yw1Em&w?TFI^vb?9(BM0 zwhH!jNbx1qy}TW?(nuJu)`uccSQ+}Zxe~CvGrQfl=ffSOBVj6+1l=yZ!l~9zUOT>m zyEI{IbhZ++DtxZkl*ku>rVqaXx6ap*A%7&>ky^cb_PpuE!Qc6={!ZufCp+)}I$ru# zf}{X?j@F{d32$kJx-uSE>ZyN{W=K#ULmZbMYd_%lLqN5> zSFg&Ib5CVQY4(SO+*XRcFzr@GJvEE@W7V2DhIu*dinZI~GrcgVu+CbeD)UQOEGv+O zGw^Ds_SVwn2fT&bTj;EHRKnYeBli%H-E0DG~j3$wK-2bIL z*(=#hl#IHgvOGuo>t{3J*(Sy{BtGm0ehZU5-v{+Hnk>myJ$)X>ogisLbc z)1Ti-zG#!c@H={>GMK=0(4))w&P4?*9c*l4{fTk~kAKuqgge3srUgr#8iBP(GQV## zSg;P)2&}3#`Os@TeLh5r0qSC%+<6Z^wV-Kbybl;q%mSralY4H~!?qVFrhuJDdBq~f z^*QP{>lN2P@RagxjmQ2;DmP-)Py;#48BPH=U5EtunAh(|CLh&(%x<~(cCEjBy8F!1Y*PomHF=nFjp}#P~ zG8WyFDG-U-cRKlbVmw?rCka-l65O^A7moZg_3y{Uf!Jy}jwFA`oJD&LW^I*!pNz5{ zxD^Ll%xH`Y(>>gYf^I-Jjg;?68!43((W)luBH1M~D#+J64QOeph&1a=Q)sbFxdJ4y zHWtP?c6Tik@TUeVcXY{XNwqXM>Yca*R>C-nMvJkfDDZd=IkDblTvRyJy=T7NjY&~( zLGqhlM~;~7mkp^hL90pS>2rp>>~9ZJX^sK{hR&bGkUu_LYe>IBYMMk(|D?fN^&eYy znrGJ0pEo#g%dk@w)tDA?S+~~lPKbmL$QZCkX!eE|)+nP#h@ejzjMpcwl4^0ZOEycU zS#GqFE=_W{2HBOPZdq}1%`ko&$EC>sA*G?>BpIf^(ro-Yl64M?0uB41DXv2QnMx6m z$fP|juYS*lkiG%+6bLWY{NX~c6SJQ`I>bVJ15>HU@0Cre*UCE^0B@NRXhEKd8>bg~ zu*G2eq=7r5ReOLXMc`ssWZRjxJ-}ffHoj@Cv8)|LwfTN~M5k6kwGm#NzlJD8p0KB3RmU=gS<%<mN(QfPl}v?9nM_jwMG-|Ih4c;9t&F?(o)J|{A%9X6iL-bbS=tF> zwBf+QYL30AGtpEMC1(1j_P40T1~Pu?p>IOVbppas7{&SVGx6zRjO%Z7e5x+m-=(|m zyS&=sp3je%gC4B>_~H?Yb=d9;wf+?FT(^0(my*Ru#>E)P#2s=>^e)jdi@TE$pJvR;bqSGj~|kP>`TSxKo~DkhnY zbVj64)&&w~Y|Emhi{d{&1q%J=K|k`vW2(#|aImp8{y3^Q-IVMpl0-0T3(J~5mE8CF zKeuQktdgcrI6SAyh!2P9xzSrzRco2w0DlH(8M;3f$r4~biW$Pp!oSi1*@@TTsk(nf zP#rI2=}H0~7YSxZu9GwZs_8^77D_w9ToCQ7ky}f!OM@TO(c6F8h!X9ReX4k|+Qm;* z9|yV;o^|8N_>(sA09R1gwR6(?z!bM)OV_}C@Pe~l<#U}o`@?`?HCoKTSK=< zd%KB8)S%vjX)Yx7PytS$_}k>|qf9$T2cjnu{uO82uTJ&Nyh|m-lJGSb_EY0=9vc{e4(i|1B1b z;cUl!4P6bwPwsdwe2CWIB6&lExA@ZJN)2Wkm8iDA!EMm{)!**`!~$*4>mlK0ZFl3v zfKNo9r|>VUrlr>FHa0r-OFW<<^X|2Mk)D&gV)3Y+zm&l90OUu#J zwYHL`8sBu5;2SVIiVnd>lkpM}VNv8sA}XiGb*x3+Cst{x(u_AZX|^^d7bn2Mmj`>r zp}M@h*PoD|IQ8!-!$+V%kw@G|WGI{>K|ho7W`)e}Qt1H2a8DKO2gzr_6fg!Zf0C-+ z4j2M@yVrjiH)6zz4|qm#z*TPvU!QIYEA?E}k2G!h5@d1DTf~dU;75M$tp4UE^Gab6 zi~j@msn-C1-a7lmOwcb?r{|d}d+SQoX|~qNKErV7n7;ese(eQU_Y(ncaa_%~J_wn^ z7$D3}GARdGrYy(Cez)!CFSbzq<`uA2$Bl`IaE5mlAJ%Bl;2_D0Up2Js@3)XuJFK!t zr~eVkRzca3zFo+37jo8b6~cjFhqcA-wSOJGi*DogY0uB=QX=+ChTp#{-R^h{kLkmD z4fp4%xrWyo3Y^xy9QDd~4HEYOh&3+@vfsq+q_DHV5*Ep=DBm9u-UxI4qjHHGwjkL6 zJrM;S*kJoOFp=xDSQu0aB_+WdO609nEc%U4NCsx@^p^oM*Q#{qj}0DncHSd zRjgy+W?LWLE=8M(Ld!V1s3&CXU<|nK_RJy>yriohaMvL^$8kM(M8^GRp}IbFkEu zyh-WrR6J933$@7?Q)om!SLebC>fTf_{SIp>olEBTGI#1Ho4pluM z@P&!USijEPHBpQ#Yf z$lt~9^N&BpGg6!AjP;KlGKxn1Fu+2&h<4J5XLe0Zb!Q|WEW1x(r{(26Y^`mkXn745tRH&>PUU~(D&%0>7ySz9_P%_KeqmcJd*4fqL!M>PTdOsiMw>+@7Q^ph z={eG{z_eLlXrioJ-D4LmhZ$FQ*|kupm8wf;v8`|GA2DQKl!cco$S*0+`XWzu$16&3YGhi@ci) zzTCD?20uKO?Zz(9bkx8)<9z&K9v6!TxjLI{Uwp_R;(>4iGmkaxT+!O?AQ-b;rsHA~tX!r> z$Ns|T;Lr!L+pGQa09~h(er@rBgxe5^G09CR)qYc?{=mL`E;(XWFQ+)`l>UuGX=JtK zwVnGV*jIG%o5$rRUIbtm#P#XAkZHq!|7EV%za^D*d+_tAf=5qZ9iM9oeInETy>ZXV zmg__Pi{sOd9QDC4b5A$UX5a{=ZJnBiJxt5Smdhh~fHX`d+`p1li#AklFfSD$EMb`A zSlHRKvU8Tcab^8nJJ2$ubDDnLUBkZqZ9usgxoVuA*H>DO0}kkt$7+^AHJpxeON?|& z^lt_s`s6U$1|<-6e)OJ7eVfoVbv1K!;Yc^OTa{fQO&=#EB8n9h0w?}q>z6}=d|(L+ z&X7}ygx0E3ZjKh4H?ZVklNe#{uT=W0(x&pg!^*0VF1$&$@Z%XN@!t{O3EOWEPd<7m zj~QI`X7op?N4LON_MOaga94E6K{_gwKQl(1?K?M+5!^I6n&WwHsH_y zaEW{{;Vl@L*P3%_@!c}2AB4=!$<$g+Q@3b&0L^w-}N#Y)2H zFM3E163)1E{5hGRT5=$-FeRkm=npfLKZE(urEd&C$fnjLBbwLb;e!Hbx|WZ|^S zjNt6h8Ns!+fh)#8)BH8gd!l`;x5X145Wis*S~@F|7t6g)XhN!!r1WtkM?fw2Dsz?u zqTv816#23o$8pejanP9xvP?nB_Sig)a1SEW`qYK&U(z-RkPEq4xmkxfdJx~Bc^2~d z{_tvLjWTonJ>|Mw4Nu>x4Mm`vw7{C;Il&tB?&_M`Gw1Wu*n9%N+)d#F1 z)&b+6Sl{xqU;d7>KMwsnf{l2*;BpPYbb0~Y5XgiKTpRk%iY~z~eVY?~+mM27l;*bn zm7cFJA`?Yu=}*W^Oaw~e*YQ&gPFj3o4!NG~-3ooZYY;9)DrBybktR_$=$J}{i&_1l(D?zLR2@TtyTF!ocR3Y@g`%b@Leol7o9L8BrzpX`2BZe=mHNp) z#EFop5J8LWm6ULFlp@66efo}txFlf!BZ*3TBBr1S$zno_f}bf;;-9|X&%=zm0)2w~K*`n@8ZuSNG8(?1$-W37R~DD-yRnBd%< zpQwe8wh?CG2e_SzKpayXp4)7&|8BQw4?wHkLCW+OIME}ibb&3`vFgBCncOo4)**){ zFDKW?ugJX<0O1+(7C{t$T~`Iz*G|D+WrJi;G|+u%ej+2%atBTf_(^-!T+J1omb#ke zn(A0Y415OCAj>*L1MX&J6TUmGr=X=SdvfDnBXmYY&Amy2r${V(zMt?tkF4Z}J5+sX zo`Ji!Iw+PtwQhI(8{u|SRg?I@1cLGM-f7I!`O7+#ynuILhr99HSZ8U``R#f1dFLwH zH>G5+I6QoOe(zHnYN+rPIX^T7t_pT(H`|{$*DOblZcIz+WY-rRKndeB<{Uo zqh7;d%WwDhVN{P=b@}g|e|kX19QICY%D^DPeRIuP8ZZROIU%Vyw0#!`&Qoe1XCc<< zwI9c-eQpQXQ0P-tmWT1KMfu$fjlPtUU61h|U#wjZ{BQ82&zZGT#N0w-MdwjTti(^7?I`&Wb3%_Sn$+&mUu25-WPhg`drdYo7Xegt970d-BjRRt-P^k zSy7`Ee*5ioNH{4FXNkBh%AMPxlfFG~z7u^iPT%6F57~37p^?;vK53VVmNW3sut{Uw z%FH=Ln;GOEK=gna<1Uvo7^-J+fySPWD)=pF+=ADYcoNHyg$-&0RrN{`{w;e1b`Sht z<(Fs47voz`k7b(4w3eUyTH|TOvf%>mkvxnS%^aWSnKQ@mF(zN(TKH$-a2Lk(k<)y3 zW1{TQV*6D61odAa>r}%bleJ(~pMAwrdemlqm+t?rkJ6xxzPa*ew#Ra*?fOoh}94S4X1$}1JZx!{`h{SI(aWpg`J6{WvYkSzT~6hRQ~}r3w023jwsF-PrLd;NdP+n z(#}9FVpNwo=ux~47Z`=+)6v&GF8>ZSBBb(7cLcJh`5SVU|oaO0tS zv~D)F889)cv&7pIbShb*Tu%9NE}1z}5Pf*6TAGh^;ZQa1AEX#7F1X7XJG|@l(cGCe zL>UT2Z4PwSEz4?!$QHNH;=6E+Ee%UPc^h(D*Gz9wzMTxuKR3ep#*IqYC2Sa1M=bf_ zQmj*mtQ#VZ#fX@QP>?#_Ur#J(&b?N$oKA!O_It8yi)mzyU_PMY#NBATdE^<=)rWg8 z_uOxr#_z>m3OaAkI;-wBaA@;l-TGKtY(~gGssn)Ot|)=;o3$rvCqsWhT@O;GtO)d8 z`trWsm$n==bsANX_{-HKbe?4^_;4U;C*@d~^Ln5%Ppv#4JIb0KH*tGvvWsZ%YK} zb0|zE*dEg%&>u@8Y*GfH9mq0q802F!(7gD1VHo>GxnKQw&!-SBv`ApF8%Pqi^b&xa zNH@MO(fb^3@d92v(|8RoNe%9}ed`5dFE-rb8pd zrAsg2=(xXA`D+EO+1dPzG~c2uV^9Jh1gT(+lu{(Ugom$1TVSVq>O=U6rBhFYr{kCA zyD{6Ks(9U>QJUiMLJUhFpHid)b1?T{ynCr25`+?@KTCX$<4?hC{J6qI{RYF}!+5|1 zVE8d{Dc!i9(?M~j*E{+7ccgDkwyJt8>-=~}u8#EfY^JfUN(&ful`p89hbIA*LS&Bo zLIrS`D72gT-#_f?mq^NR<&3O}iq6Q}VY?}fVPVIA(=i(`h~j}yMyC*|OApX0aJ8(r^TxY8GFRQ`xjpc?|SV}263(+P>UFZxp>9B)7`(P4wom^uz?XZI3 zZ0dJ5D>|3cMNBN;gm7mSO)mrL$C3CYI@~^ilKu?mSQ9g?ekxVYf0(5Sp{N)|d|Q)3 z8uqlQi$gr;gIbEM>_w>dzgfe=L}}iP?~^8+<~a^sf5Qq%W7*Aub2gE**Jl0BoF*Tm zpf_|^TXHaseTw7I1FhV#yXfVF-k95kzp+zq>a zzWPU_UDRKbJpeHr6E>athLvTp-D;ODFh?tXa@ZC)fy|*I0!bHV(`b1L37ym-6Mk^J}|MHmnyO z&k+BRvN~g&O>?s+IXbXGwm~w=4mD$eS}CF z$Pr`?G^n%(-_G5%{$v!V{r=Wb{c5gX#AAxB(QRXD`Vxa~iyy$l==5H7UVDzQy1)9w zaJnWb_HWH*OecoV`Kxmwdpfwb*_RA_MsMQ8F;nM~e*4Ff(v#Bm!>1M4`Uv~F^r`ee z^49#3eVZMg?ZN+$wa1swm*1(pq3mVzNx!a?KJ(Z1n(aAtal`UR%r?N$amV0ExC`V- znSa#4!rX7S1{cUS<+QwTlFu2bu`C|1A?Trv7c{j^_Ln&hmpKlxZ1&B<|5iNSr*5Fr zSMB~CgP4vl6ur~lQ`z!Rl-t@472cNIyE)VTQ zk3R+_1>*A8Ez;mo{ZE(V!w1s{&E3nr_P_M5a#~FRmKpH{iK3mN1z}9qvbrRUK^Bd& zH%*Y2aio(<7(td%Cko&pDEL7Y$z12qGHin?1F zs0G!}rC)%;Tcv-)KFg?+DkT#T)*$0yF1MET>85>HzGu11n{|)zcRz{YVmcISRku6M zzYZqbZMZ99$bq&w?DXh}@O9qK!X|y4`xRepL+s-r?#udDnNtP=+`cL`3G9V8_!c4F z<*$rSvG0-hk(~mR;n-OsQ%CE6EkqI5v-h%L{*`-u4Lvr!S6%$MZvE$#72HAY_PzSV z9!u`Zacj9Fa(ON|553&wSRsKR?c2#FUbHRL@8?Za2!1q5M*GV3U!jz6N9d$^CawQ$ z+si+Q%Gon_`wl9jXvMcr;m46STfr#3#r7Pz-&A#WMiMEHY5SxjxUdVxg zXFUPIrPY-(aC4E$lXgj#bUyVX&=4*90uPJm!B$vxKl5;GK|NYdCVx`6ZmG_DTuG?g z*P~z7BmBG$YLDBx*UeOGf0DfAEa&2%Gc5FQ!7IdPHPYEK@c)B*pNHV#9s=DrCQG0( z?)^>G&vW5dg6|F;qv{RgH_@{F&@heb*#u!Ag8Svi+nInj@moxKvf)LP;Q3*Q%;Avq zbb7M!l9TSnM&wQ8ee~PY_6^9f5cQkGENp6xcJSTQK57I@<#+ z{$TK8O?kw{gCp@)|}>Web`Bea##-ZAI+0p zbshno&1vvPJJB*|Rb-8kVHB~@6QWb}mE{HX6)5$(ctB|C@=0=anCUo>Gkwo82HhJT`7C)tnqHbH^2A?9yEN$TUE4v z)wNhFT3VzPE6N>ty-I9UgJA$k>iV7Zdvmy?=#V)(vs15iRyS_7H4TpL!ePT*k2CAb z3_Z`SdQXN18)Ig+)1ODx#dfEKTKJRxQ&D}w0xbK6T#nZrJ zPu-#4I_}>h@ypJyuIz_R*uFLtPC1NcXM#1WqKp7#*l5n){Fwy%vm4ncq3HuE01Z?aFfo_TqGe#h7?YdR%x6jElGOU1Q@x2fUx*dn*J(B zfgAfqzQ?7jZ$kWYqQQyjpWL@^3c>Q~?*@%ScNYtYNJrH%VLNUhSuBw+80=g*Wisp2 z5+?om^druT_6))7*BP}bR;NH!07>VD?In_H${THSN?r6>03PlJ92jGOq&}+y1!a%V zncVI2RI%N`vfL8!fE|>y{2min30(A4Ph(I0T1UsUDPyqtbCd>6Dy7_g^N_UxxemMX zDg7DUy6WS%uh?rK$3~!gyQ%%$el?C6ids6^xd&r9(OY9EIkh)-7W6{*Oj<6qMyMvX zt*^5Vsg{?Rri5O-ju2If)C8$mS++&zu%pcuLl>m)gu9aR4+K)r8dAmz%ged4i z76kMHHn{fU!SYD(b$*r6gW|R=OdFm~{T}*1T%A*JAmO&QC!Azr+fF9d#I|kD#J1BD z+qP}nwr$(?Kef*}`{J)!7u~C?x>i@;d`s{1yV*dUGHEG+l4Hna>bYln68KH>Hp+K3 z?)?ddyV>gbvf)Cn*O?$}Gw_a3OAkC=ox_|35p-Vd1id-)zBAxm(XL!ouj#i_>tEs- zADB*&BG}dPp8O8clm5aOkw!q4BMT4p#U~f@&%1t{NurU*oZspO!n`@LxyhfX+DDrQvGKqZ5mCX$jLQ>a^m!tV2U`l4Y1pY*g2&p^DlqM8Cbtp z@FQn$M6hxw+-E;-yh^{uVogMpVr>9MMumr@F<=_)Fi#2*nYJPpE=%cmLy;*l#wcr* zrWJ2p33~(+pE!f+5U=IEm|`(U6GH7_Q6Ul=1w)N(O%`jhE>W@I6*453Cg)(0NhAaV zvMX|;FHCQiZ-Q?dqijz?GazXUyvBoCC}DX?6l|^R<~X_R0|kNo!kscHhFQR&Wmq}} zTJFuC+#Xeo9ES=gJD((uB-ER=xJFYJY?NJvx_8Mn>F%T zD9--0dd&T`^+Xv#`K73b@!Yo_&NG1~OCD=yF_X6#MTk^!@&76SWMWoWw~SX}C(bI7w19hki-f z{pIshq>fLPHb7XTl!xH&)&^axFlTkHN;`3-hHBM<8co9HLK|@D`YY>ie2jym>QIXaiNZdatVzqVF(g8m<2~@be3?DY08%S)pqk#?B+ZQ6&loU(Q>mFI9tUb;1 z)lo)dg6%Yky0VP=wn(HN!8QA#2Y)L zurIFSseojgY(Hu19~2;d;roF)dUEV3Flq2~9lJ9yw%M+tWBDq1w)#uw5J}vv3HL@H zV(5`6&cK6$CzL)@xDp613&LQ@Ht5_~0_0pEKTIY%F>Uhaj?0sP70A79^~iFMVWxtx zLL*hTU~n3=qyR@Kb$k*U&hn$(oEj$EpMEOrACzRK@rK#tMkKMf90N>^Yvm49vDVd? z63Jpr852Q6$+d|hFw#xFe^g`0LJ-IM8t27LzyKMbcwYW|K(&#`V(B59x@mZ>yx^5u z$v`5nx3PLoJ&=dL^jr2rs;m}XuYoNQEc~)A_{Incw<6EBT!Y@`h~{p67vIB zgJy`adL=AQq1Z9gL8K_zqD&s7@T|$n-jOYqlXjsG+Q>fw?n1x@-;A1qK&U;F)3>`U z5P<1He^0`NDu`#EnQZ= zcu4NAeEMU39%?{`%BD5F5LNa8JxbsJ>_!f8pVZPkHr5;ggQ>9`pKK~}jV3tCs{Nkm zpTN_IclV-4!_7^_79%q1H0@kh>V-PMywn|3{av3tBMugSWU1(9hk~s-E)RW{^qV!> zcmwpf6Mb1OSl^Jq=g<=abt6;XokV69jk2y~EMztuQyC zaZk^;8aYjr8u;|l%-)*wLufLT!}7CaZ-edjR){2U{%iQ#thqmgb^4a`4-{`ef{w{% zKgbEQX)IPA3;on{vURa|jmR_RblF$p<$>xx)ka-0nf8v#BicL0C0w)MC@e$py>Dy| zE#Wi(5<+@qa1Z`=`unA+w)mSzYDqbzo)?;hZFxEmv`I^FyC2`4H^S)FO}#&Z0f+wy zjU;0T&!`uvRI=mm@U2*`a-$g_JL1gvjc^bmz9i~E309e=W>`{!M<6EYAv0{C#Bgzq zH@m9gxlT{F*7$SY{R{pUzGshwkIoc-0bC7%-vLg$1B%D6v|JAcv;11}cmvVFf{3p6 zU4_9?nle?xQ3FXSe-6VbbXq~W;n>4C;gH2BZD(Ddt8~X2TFT~x)4mfZ7=*s$e@SQ~ z+i}{578JL*k*oTq;JFUQF6H$^SUgMUg|lxON_@!7o*@y@Zrf)j4$Xr?OcWt+1%?~T zELJUI)35o3hjLbZK0%=+>mp(Q%c5vnr9s_){UYKJijKxuV@Px; zj|lm4jA=pRSbm1>Q7_GfZT~I{LdCP9TtsQ4OpZom8Mb!ui8j#uOsm$e)!nN_gIq-> zZeu9r>qzQMA^uAtfiNVE=Dz9uW1ns=a!atVX_%iqiT;guA#olc6h9)B3Bwsp#~g3Q znVWydo})VZ;86SRj^;VpPVYCBzv+(M`Pn<()K9Xn$Mu(AVU?b(pezlCCT#F@FuA+9 zwiesYCi~U*VXLbTr!VwXEiZ+la*bS$`$zW`~|?i z-6YxAADBe-9CtOtkK%V*nM5Idh5Z)3e*v-EPd2d)dDX+s%bm(ppwJvDHbqJu((Ts` z1_v*OLdzqS%!8cwofMm!#$_R(6{VRruin~9PNIF09V!PjFs5|wK4vCps;FtNI=Q`j zNYj?hYsLMy0CKQ%_P6sGeYBZSlZ~Zd} zyN|TzZnvK$PNX%Ra~dlsJBOE+OABM<+-K=oNq4zFtAr}fo%|D{S9wrTBe5*4nw@aq zQ{_vaTsQ>?>_56@UbH?0KsA3#ei=G4>3Q5XWLAlFVsy@Y8h=b&b*<3748Dj}4z+6- zVXC;y?B1=OuAct-cea}Eo}xD|E3+7Z)r5yQfw!Ma=@g1m!(wGsHF?K*)p<13^p@q? z5@|}VkXIINk85-F)yOEQ>9_tsG}HJ(Eo`_kU7(4FdpK90}PXc8L2O^@f(bh)7_A>o1oTwcZ)Z|ML=@Z>{*GpHfmV3uqvri|BsP^aGU3g%#?vY&nuK626YZDBjRSS=j^&1?X;SpL^S;9vioPm7XbbhAV0p!_c z#-jyhrO2|<$?_~U)FJ<91sck*_WUX#>LLvW`GYE^AR}aj)V~5pvkMa8JDrOU5m*7j zSAl2cYgzShqpOmJ<7l;A13x6x4X-SkB+LIanD9)Aooy#>Brc>F-M_u*6Om z-HtwwCkQsKgSZNjO`3nb)e52QIjC)To%D)z@zvOUw6#@kZ1^@XZlx@>R(DLw6w2|` zyT1Cmt683xrSn@HkhCX%L)C#$P{C34 zP+zmbqyI(2n&mxhuKxsw0*4}mY&L)<1flaED3Ap87t!b=r(WO(7514X4OZ4l2vxDz zs8F@Cu(GfyYEZJUcp8|E+^}3&EC_S{$B5Nx8|SOAN_g&cxRimS^SV3icrp28cO`w9 ze9W-nle&~h25;bIz{dh$E98p>TjY$z@24S=Bdh7WjvDE;r!Ln-BDGwq&sv-ue*C5% z@v0xGyW~>iG|hPw9yiripXae6Zh5Spa6cu~5W&YyW~{Wjh`Vw`U8tH}{gST4F}0j$ z+4W#Kewk+4ri~q*6)E)^77rvfn(^`Rh9&uJ6faFD3ylUYUp)X2+JCoqn6i+Vtn@j* zduKf!SN<_GkWuiDfa#Rb5?K_lVUuhpr4fGi3k%gMea>dwZZ)-#6vn#YK8cxqT!Zgn zHmvsu!DLBJIUpbB=qo2IPt=}XK2Bo)Z1->KObTpDH)%{TK9;;_VL`YtW@aJjeTQ8O zSTZ#&CZ_x&RWv&AOf`OiwNw!CV^1O;Vd008&d^YNvOTtS<~X5w9`zb}QcZ?K>h5ox za~cbZ`&DB!vX)4Sq~sy2qr^cSKQNKS@Z9r~I9FLZnZ49M6X#We?22>%**He$H>SnY z_z>Rii13@cutH4o*ob^$BraYbWFYnynK8DC4bBd!Jhlz^_+}RqfEPHaDM8)}Ax+-e zd52tm9U$dp4GIC#g%#-|suvyI|;M1k*2k6aR*i&dhGNgwk(dlMYk1M)0a2Z}){hbz;B=~zOTVSF*pDGx5M$IHwq zp1)hTMu8JhzYrx0C|>@?q>p-j^%PRjDOkdf8U`Oom3-vDOlZ7s_^?x4A_LQ(&K~=` zCuYqzDFWrAh1kAZjCfBNaAvrPGFNnUOv^Iv!9XvoR%B%1u(xM_#>8aqWOttr2SexG zZsjg?a*B}nlgm|XXS?aph}BMF;VvSg32Pw)jYk|H_ez>lpF#c}Y<~u^}othieGx?@mPF{?^vOr?`zcC@QQ&cxYS3#|kx}QWm zvue-pWL@p~e(D+U{-BWHaq)a)0xa0#fNStZ*Gzc$a4$n3oHa2;=->WxR^l219dWH^AQ|(Rat2O0 zxflev^3mXd5ydO@u!0$TN4xpXT%={KN>xPqymqsYq;Nd)JAK(S!L&0_ z%>hv(S%e}b;WNI4KrX8pk;#Y#9gtg+Yea0`Zdw~Gi7fE55ES$vKb>^pIF+MZ=ga^l zH~I}4w4WG@vwT$w8oVCLc(vpBjWM4R8*bmXoL|QW>^O~n7Mpq2T23@db`;Vd49s2; zMnJa`?uo8nZlx4i*$}M+xf@xe98?OB%;vMjqqHMKZ{4Jji`_L6)YGu-MrCRxCR9J9 zS#64HY=ftcQ>vX0iX1Q@iwfaq?_vi7EdKIgAqkjgK7X=U+e9h zs@dB%+I{oFrPD#-)ik~@X@H-Gwg_(FRGWZ{{8Bq zMB^)N&0q4KNfYhQNL}eC6l%aQRTiZ*U(cT!fOK?PlqQ79KGt6`^)g(F-XjKC`F=Z;M>n=Q-eWDZ7@ zgARW4%Y~DQ3J#z8GpIyCo2=+E_248+@d8A|%E1Qg%14n}85^EX?JcmMSW59!Fi9Cv zq0KZ_+s-+;?sJZOV#RX|=cS|-NjEMwK&eq6+afAKlW?lfiqa3MAn<(BKxoFGh}=Un zB0~|48J?38Lv8j~TgyKcNAwNG+n~q8dy8kCt}=#J#k&$)k7eK-jA(FfY?deYLF ztAEyWv{Xj;kOOtawDII4EuM4x3wrBXN}VtBt9c9t&9Y+SX`0h2IWx+ux5@3d(wwyJIv`){68M+0Kki#@PTLX|x~ za*j_cT2MJyUf%eAwI6Xv$h-WP{D}0Tx{+WIZ4Uw1S0hN7| zN_AhH7*BLjR750Bf>4|ge%Bg}{n+K;23+`6Z#%Rtv1^)pq~2A>`Jbutb1EzY(?4Zq z>eaUgZ@8z)ualRe9o=S8k7v^|8}&{(hW1c%F*!ny=T!WuYtiO^VUx?vMv;qBy^DZ! z8ah=4rvtRaHi!wK#i&Rn{%-u#cs%UM_26-<+wc0+>{gvpoIgY>J#?w#B>nftXQ(V?xq$=^y9C0sS+3)#Mubk(q_{+;(4#14 z!->U{TILUmsV>gF|l?2${bZdD=DrK z7yty6L;m8@6Bd+~QqFoL3=`z#sbg&8guSZ`UzPKO@Is`aaFOwjcomySAbW zg?ml(Ja#Tl4;w>?>)yN8Bq`B~ydJZp7AeN#@f@w|97foZ9!Dl=G!ZU9yX8xWjEYKH zY9vAW-l{jpKcLr6}+2;7KTjh4U0GH4pmIb^&Pv=hnilH_ae6$e4oyDH`y zmj~x|cC+71&Oz%taP-^jgz)%C2TLeOh?d2VS~1x-hFeC*FbN`48jx~A)5d^DktlO; z{LA>#EbOBxm5 zP1-L}xygtabr9F_R$0#^w=N#vG^{LE6nQJgxNQDXLeIbld;4iu%*sug z;_Z&dMgEJ)P?=vmR2^Jpz z5&dYuE?$UdiR)Q~1iaz7V4SNi5rEsY;G_KHbNRQbr>_at$qU9XfKpEPOC1k0`5O^$ zW<=4js~a~Oy#Vv?{HpZ*-!PBCck4)?tDAxDjR=+{=lX#p>hB0)+0a?pLu95JJMfOy1Zy%g!~n|=j7Ii~s- z3U8-j465lC$xY1eG7yXl+DI3nsXo$Y|M|GjzuT}DunlSI6Q%Za3F;C}G4nkWalM2( zCklu@|CVw|ZL8ym7Rzxp=KF{6TDCp4sFto0)O&M#>7Mj;!`_`np4R8VleiPQP?Wu= zpZMOt=r6I^{eaIOsA9MbAl6WjG#@~EFbojbk02r2Ju*)pd+Apg#tc{M3 zMomFb&d6tL#vTs(Zql|pE&F3?lQ>oJt!ki4;kHQsnoGL|n z(syw#XX0sI4wUhRM*x-_X_p5)7cxtvmsDh;&xx=3jM7DC_kf^yU_MIziDZ5tua#6! z`TJMxizCI&3g9$L7C#)KO!%<-5SN`Ko3n*}_~Q!An?{rNRfQX=h$A+F7bkybR%BMB z6U$r1JL-++k`JqhJ&B+Gf_G(w3{ZQXbnlcPdyzs&3lBx zo@j# zUpm+Nz#tVWXYsl^8mdTl-vFtb;I=xM!Q)ySD)BWU$SW94kP6{#%yb9xDMNmi&y^V= z&YxkQ2)_`Da~~D~1_(Zm&f}IwnT=NB{z>{S=)G%zv{OXrrY@cT?-jw<+i(BIbQmb# z-In#FslxxJ)j(?-d+W8lx8gHn9qXKj2Yhn<`ivt4%0Drg-O!cI{b0o*{eRsG$(r28> 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 delta 236619 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

    4J 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 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})